blob: 087fe1efa42e4b89ae2c2c1abeffdb8189bca36b [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
180 //8x16 and 8x39 targets by default
181 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
182 (qdutils::MDPVersion::getInstance().is8x16() ||
183 qdutils::MDPVersion::getInstance().is8x39())) {
184 defaultPTOR = true;
185 }
186
187 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
188 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700189 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
190 HWC_DISPLAY_PRIMARY);
191 }
192
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530193 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
194 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
195 enablePartialUpdateForMDP3 = true;
196 }
197
198 if(!enablePartialUpdateForMDP3 &&
199 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
200 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
201 enablePartialUpdateForMDP3 = true;
202 }
203
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800204 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
205
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800206 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
207 int val = atoi(property);
208 if(val > 0 && loadPerfLib()) {
209 sPerfHintWindow = val;
210 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
211 }
212 }
213
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700214 return true;
215}
216
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800217void MDPComp::reset(hwc_context_t *ctx) {
218 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700219 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800220 ctx->mOverlay->clear(mDpy);
221 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700222}
223
Raj Kamal4393eaa2014-06-06 13:45:20 +0530224void MDPComp::reset() {
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530225 mPrevModeOn = mModeOn;
Raj Kamal4393eaa2014-06-06 13:45:20 +0530226 mModeOn = false;
227}
228
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700229void MDPComp::timeout_handler(void *udata) {
230 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530231 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232
233 if(!ctx) {
234 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
235 return;
236 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530237
238 ctx->mDrawLock.lock();
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530239
240 /* Handle timeout event only if the previous composition
241 on any display is MDP or MIXED*/
242 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
243 if(ctx->mMDPComp[i])
244 handleTimeout =
245 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
246 }
247
248 if(!handleTimeout) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800249 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530250 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800251 return;
252 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700253 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700254 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530255 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700256 return;
257 }
258 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530259 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700260 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700261 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700262}
263
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700264void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
265 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800266 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700267 if(value > maxSupported) {
268 ALOGW("%s: Input exceeds max value supported. Setting to"
269 "max value: %d", __FUNCTION__, maxSupported);
270 }
271 sMaxPipesPerMixer = min(value, maxSupported);
272}
273
Saurabh Shah59562ff2014-09-30 16:13:12 -0700274void MDPComp::setIdleTimeout(const uint32_t& timeout) {
275 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
276
277 if(sIdleInvalidator) {
278 if(timeout <= ONE_REFRESH_PERIOD_MS) {
279 //If the specified timeout is < 1 draw cycle worth, "virtually"
280 //disable idle timeout. The ideal way for clients to disable
281 //timeout is to set it to 0
282 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
283 ALOGI("Disabled idle timeout");
284 return;
285 }
286 sIdleInvalidator->setIdleTimeout(timeout);
287 ALOGI("Idle timeout set to %u", timeout);
288 } else {
289 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
290 }
291}
292
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800293void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800294 hwc_display_contents_1_t* list) {
295 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800296
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800297 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800298 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800299 if(!mCurrentFrame.isFBComposed[index]) {
300 layerProp[index].mFlags |= HWC_MDPCOMP;
301 layer->compositionType = HWC_OVERLAY;
302 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800303 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700304 /* Drop the layer when its already present in FB OR when it lies
305 * outside frame's ROI */
306 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700307 if(index == mCurrentFrame.hwCursorIndex) {
308 layer->compositionType = HWC_CURSOR_OVERLAY;
309 } else {
310 layer->compositionType = HWC_OVERLAY;
311 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700312 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800313 }
314 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700315}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500316
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800317void MDPComp::setRedraw(hwc_context_t *ctx,
318 hwc_display_contents_1_t* list) {
319 mCurrentFrame.needsRedraw = false;
320 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
321 (list->flags & HWC_GEOMETRY_CHANGED) ||
322 isSkipPresent(ctx, mDpy)) {
323 mCurrentFrame.needsRedraw = true;
324 }
325}
326
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800327MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700328 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700329 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800331
Saurabh Shahaa236822013-04-24 18:07:26 -0700332void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700333 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800334 if(mdpToLayer[i].pipeInfo) {
335 delete mdpToLayer[i].pipeInfo;
336 mdpToLayer[i].pipeInfo = NULL;
337 //We dont own the rotator
338 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800339 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800340 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800341
342 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
343 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700344 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800345
Saurabh Shahaa236822013-04-24 18:07:26 -0700346 layerCount = numLayers;
347 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800348 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700349 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800350 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800351}
352
Saurabh Shahaa236822013-04-24 18:07:26 -0700353void MDPComp::FrameInfo::map() {
354 // populate layer and MDP maps
355 int mdpIdx = 0;
356 for(int idx = 0; idx < layerCount; idx++) {
357 if(!isFBComposed[idx]) {
358 mdpToLayer[mdpIdx].listIndex = idx;
359 layerToMDP[idx] = mdpIdx++;
360 }
361 }
362}
363
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800364MDPComp::LayerCache::LayerCache() {
365 reset();
366}
367
368void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700369 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530370 memset(&isFBComposed, true, sizeof(isFBComposed));
371 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800372 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700373}
374
375void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530376 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700377 for(int i = 0; i < numAppLayers; i++) {
378 hnd[i] = list->hwLayers[i].handle;
379 }
380}
381
382void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700383 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530384 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
385 memcpy(&drop, &curFrame.drop, sizeof(drop));
386}
387
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800388bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
389 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530390 if(layerCount != curFrame.layerCount)
391 return false;
392 for(int i = 0; i < curFrame.layerCount; i++) {
393 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
394 (curFrame.drop[i] != drop[i])) {
395 return false;
396 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800397 if(curFrame.isFBComposed[i] &&
398 (hnd[i] != list->hwLayers[i].handle)){
399 return false;
400 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530401 }
402 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800403}
404
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530405bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
406 hwc_display_contents_1_t* list) {
407
408 if(layerCount != ctx->listStats[dpy].numAppLayers)
409 return false;
410
411 if((list->flags & HWC_GEOMETRY_CHANGED) ||
412 isSkipPresent(ctx, dpy)) {
413 return false;
414 }
415
416 for(int i = 0; i < layerCount; i++) {
417 if(hnd[i] != list->hwLayers[i].handle)
418 return false;
419 }
420
421 return true;
422}
423
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700424bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
425 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800426 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530427 (not isValidDimension(ctx,layer)) ||
428 isSkipLayer(layer)) {
429 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700430 return false;
431 }
432 return true;
433}
434
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530435bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800436 private_handle_t *hnd = (private_handle_t *)layer->handle;
437
438 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700439 if (layer->flags & HWC_COLOR_FILL) {
440 // Color layer
441 return true;
442 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700443 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800444 return false;
445 }
446
Naseer Ahmede850a802013-09-06 13:12:52 -0400447 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400448 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400449 return false;
450
Saurabh Shah62e1d732013-09-17 10:44:05 -0700451 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700452 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700453 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700454 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
455 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700456 int dst_w = dst.right - dst.left;
457 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800458 float w_scale = ((float)crop_w / (float)dst_w);
459 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530460 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700461
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800462 /* Workaround for MDP HW limitation in DSI command mode panels where
463 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
464 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530465 * There also is a HW limilation in MDP, minimum block size is 2x2
466 * Fallback to GPU if height is less than 2.
467 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700468 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800469 return false;
470
Ramkumar Radhakrishnan1a763e92015-03-19 16:46:46 -0700471 /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
472 * those cases
473 */
474 if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
475 return false;
476 }
477
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800478 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530479 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800480 const float w_dscale = w_scale;
481 const float h_dscale = h_scale;
482
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800483 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700484
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530485 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700486 /* On targets that doesnt support Decimation (eg.,8x26)
487 * maximum downscale support is overlay pipe downscale.
488 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800489 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530490 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700491 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800492 return false;
493 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700494 // Decimation on macrotile format layers is not supported.
495 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530496 /* Bail out if
497 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700498 * 2. exceeds maximum downscale limit
499 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800500 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530501 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700502 w_dscale > maxMDPDownscale ||
503 h_dscale > maxMDPDownscale) {
504 return false;
505 }
506 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800507 return false;
508 }
509 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700510 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700511 return false;
512 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700513 }
514
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800515 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530516 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800517 const float w_uscale = 1.0f / w_scale;
518 const float h_uscale = 1.0f / h_scale;
519
520 if(w_uscale > upscale || h_uscale > upscale)
521 return false;
522 }
523
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800524 return true;
525}
526
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800527bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700528 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800529
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800530 if(!isEnabled()) {
531 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700532 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530533 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530534 qdutils::MDPVersion::getInstance().is8x16() ||
535 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800536 ctx->mVideoTransFlag &&
537 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700538 //1 Padding round to shift pipes across mixers
539 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
540 __FUNCTION__);
541 ret = false;
Raj Kamalc0d34242015-03-17 20:53:14 +0530542 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
543 qdutils::MDPVersion::getInstance().is8x16() ||
544 qdutils::MDPVersion::getInstance().is8x39()) &&
545 !mDpy && isSecondaryAnimating(ctx) &&
546 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
547 ALOGD_IF(isDebug(),"%s: Display animation in progress",
548 __FUNCTION__);
549 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700550 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
551 /* TODO: freeing up all the resources only for the targets having total
552 number of pipes < 8. Need to analyze number of VIG pipes used
553 for primary in previous draw cycle and accordingly decide
554 whether to fall back to full GPU comp or video only comp
555 */
556 if(isSecondaryConfiguring(ctx)) {
557 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
558 __FUNCTION__);
559 ret = false;
560 } else if(ctx->isPaddingRound) {
561 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
562 __FUNCTION__,mDpy);
563 ret = false;
564 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800565 } else if (ctx->isDMAStateChanging) {
566 // Bail out if a padding round has been invoked in order to switch DMA
567 // state to block mode. We need this to cater for the case when a layer
568 // requires rotation in the current frame.
569 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
570 __FUNCTION__);
571 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700572 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800573
Saurabh Shahaa236822013-04-24 18:07:26 -0700574 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800575}
576
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800577void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
578 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800579 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800580 dst = getIntersection(dst, roi);
581 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800582}
583
584/* 1) Identify layers that are not visible or lying outside the updating ROI and
585 * drop them from composition.
586 * 2) If we have a scaling layer which needs cropping against generated
587 * ROI, reset ROI to full resolution. */
588bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
589 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700590 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800591 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800592
593 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800594 if(!isValidRect(visibleRect)) {
595 mCurrentFrame.drop[i] = true;
596 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800597 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800598 }
599
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700600 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700601 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800602 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700603
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700604 if(!isValidRect(res)) {
605 mCurrentFrame.drop[i] = true;
606 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800607 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700608 /* Reset frame ROI when any layer which needs scaling also needs ROI
609 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800610 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800611 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700612 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
613 mCurrentFrame.dropCount = 0;
614 return false;
615 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800616
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800617 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530618 if (layer->blending == HWC_BLENDING_NONE &&
619 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800620 visibleRect = deductRect(visibleRect, res);
621 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700622 }
623 return true;
624}
625
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800626/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
627 * are updating. If DirtyRegion is applicable, calculate it by accounting all
628 * the changing layer's dirtyRegion. */
629void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
630 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700631 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800632 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700633 return;
634
635 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800636 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
637 (int)ctx->dpyAttr[mDpy].yres};
638
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700639 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800640 hwc_layer_1_t* layer = &list->hwLayers[index];
641 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800642 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700643 hwc_rect_t dst = layer->displayFrame;
644 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800645
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800646#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530647 if(!needsScaling(layer) && !layer->transform &&
648 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700649 {
650 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
651 int x_off = dst.left - src.left;
652 int y_off = dst.top - src.top;
653 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
654 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800655#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800656
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800657 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700658 }
659 }
660
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800661 /* No layer is updating. Still SF wants a refresh.*/
662 if(!isValidRect(roi))
663 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800664
665 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800666 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800667
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800668 ctx->listStats[mDpy].lRoi = roi;
669 if(!validateAndApplyROI(ctx, list))
670 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700671
672 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800673 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
674 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
675}
676
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800677void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
678 hwc_rect &dst) {
679 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
680 ctx->listStats[mDpy].rRoi);
681 hwc_rect tmpDst = getIntersection(dst, roi);
682 if(!isSameRect(dst, tmpDst)) {
683 crop.left = crop.left + (tmpDst.left - dst.left);
684 crop.top = crop.top + (tmpDst.top - dst.top);
685 crop.right = crop.left + (tmpDst.right - tmpDst.left);
686 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
687 dst = tmpDst;
688 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800689}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800690
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800691/* 1) Identify layers that are not visible or lying outside BOTH the updating
692 * ROI's and drop them from composition. If a layer is spanning across both
693 * the halves of the screen but needed by only ROI, the non-contributing
694 * half will not be programmed for MDP.
695 * 2) If we have a scaling layer which needs cropping against generated
696 * ROI, reset ROI to full resolution. */
697bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
698 hwc_display_contents_1_t* list) {
699
700 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
701
702 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
703 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
704
705 for(int i = numAppLayers - 1; i >= 0; i--){
706 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
707 {
708 mCurrentFrame.drop[i] = true;
709 mCurrentFrame.dropCount++;
710 continue;
711 }
712
713 const hwc_layer_1_t* layer = &list->hwLayers[i];
714 hwc_rect_t dstRect = layer->displayFrame;
715
716 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
717 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
718 hwc_rect_t res = getUnion(l_res, r_res);
719
720 if(!isValidRect(l_res) && !isValidRect(r_res)) {
721 mCurrentFrame.drop[i] = true;
722 mCurrentFrame.dropCount++;
723 } else {
724 /* Reset frame ROI when any layer which needs scaling also needs ROI
725 * cropping */
726 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
727 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
728 mCurrentFrame.dropCount = 0;
729 return false;
730 }
731
radhakrishna4efbdd62014-11-03 13:19:27 +0530732 if (layer->blending == HWC_BLENDING_NONE &&
733 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800734 visibleRectL = deductRect(visibleRectL, l_res);
735 visibleRectR = deductRect(visibleRectR, r_res);
736 }
737 }
738 }
739 return true;
740}
741/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
742 * are updating. If DirtyRegion is applicable, calculate it by accounting all
743 * the changing layer's dirtyRegion. */
744void MDPCompSplit::generateROI(hwc_context_t *ctx,
745 hwc_display_contents_1_t* list) {
746 if(!canPartialUpdate(ctx, list))
747 return;
748
749 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
750 int lSplit = getLeftSplit(ctx, mDpy);
751
752 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
753 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
754
755 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
756 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
757
758 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
759 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
760
761 for(int index = 0; index < numAppLayers; index++ ) {
762 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800763 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800764 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800765 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700766 hwc_rect_t dst = layer->displayFrame;
767 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800768
769#ifdef QCOM_BSP
770 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700771 {
772 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
773 int x_off = dst.left - src.left;
774 int y_off = dst.top - src.top;
775 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
776 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800777#endif
778
779 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
780 if(isValidRect(l_dst))
781 l_roi = getUnion(l_roi, l_dst);
782
783 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
784 if(isValidRect(r_dst))
785 r_roi = getUnion(r_roi, r_dst);
786 }
787 }
788
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700789 /* For panels that cannot accept commands in both the interfaces, we cannot
790 * send two ROI's (for each half). We merge them into single ROI and split
791 * them across lSplit for MDP mixer use. The ROI's will be merged again
792 * finally before udpating the panel in the driver. */
793 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
794 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
795 l_roi = getIntersection(temp_roi, l_frame);
796 r_roi = getIntersection(temp_roi, r_frame);
797 }
798
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800799 /* No layer is updating. Still SF wants a refresh. */
800 if(!isValidRect(l_roi) && !isValidRect(r_roi))
801 return;
802
803 l_roi = getSanitizeROI(l_roi, l_frame);
804 r_roi = getSanitizeROI(r_roi, r_frame);
805
806 ctx->listStats[mDpy].lRoi = l_roi;
807 ctx->listStats[mDpy].rRoi = r_roi;
808
809 if(!validateAndApplyROI(ctx, list))
810 resetROI(ctx, mDpy);
811
812 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
813 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
814 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
815 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
816 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
817 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700818}
819
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800820/* Checks for conditions where all the layers marked for MDP comp cannot be
821 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800822bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800823 hwc_display_contents_1_t* list){
824
Saurabh Shahaa236822013-04-24 18:07:26 -0700825 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800826
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700827 // Fall back to video only composition, if AIV video mode is enabled
828 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700829 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
830 __FUNCTION__, mDpy);
831 return false;
832 }
833
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530834 /* No Idle fall back if secure display or secure RGB layers are present
835 * or if there is only a single layer being composed */
836 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
837 !ctx->listStats[mDpy].secureRGBCount &&
838 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700839 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
840 return false;
841 }
842
Raj Kamalc0d34242015-03-17 20:53:14 +0530843 if(!mDpy && isSecondaryAnimating(ctx) &&
844 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
845 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
846 ALOGD_IF(isDebug(),"%s: Display animation in progress",
847 __FUNCTION__);
848 return false;
849 }
850
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700851 // if secondary is configuring or Padding round, fall back to video only
852 // composition and release all assigned non VIG pipes from primary.
853 if(isSecondaryConfiguring(ctx)) {
854 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
855 __FUNCTION__);
856 return false;
857 } else if(ctx->isPaddingRound) {
858 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
859 __FUNCTION__,mDpy);
860 return false;
861 }
862
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500863 // No MDP composition for 3D
864 if(needs3DComposition(ctx, mDpy))
865 return false;
866
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700867 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800868 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700869 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800870 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
871 return false;
872 }
873
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800874 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800875 hwc_layer_1_t* layer = &list->hwLayers[i];
876 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800877
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800878 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700879 if(!canUseRotator(ctx, mDpy)) {
880 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
881 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700882 return false;
883 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800884 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530885
886 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
887 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800888 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700889 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530890 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
891 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
892 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800893 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700894
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700895 if(ctx->mAD->isDoable()) {
896 return false;
897 }
898
Saurabh Shahaa236822013-04-24 18:07:26 -0700899 //If all above hard conditions are met we can do full or partial MDP comp.
900 bool ret = false;
901 if(fullMDPComp(ctx, list)) {
902 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 } else if(fullMDPCompWithPTOR(ctx, list)) {
904 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700905 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700906 ret = true;
907 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530908
Saurabh Shahaa236822013-04-24 18:07:26 -0700909 return ret;
910}
911
912bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700913
914 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
915 return false;
916
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700917 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
918 for(int i = 0; i < numAppLayers; i++) {
919 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700920 if(not mCurrentFrame.drop[i] and
921 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700922 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
923 return false;
924 }
925 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800926
Saurabh Shahaa236822013-04-24 18:07:26 -0700927 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700928 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
929 sizeof(mCurrentFrame.isFBComposed));
930 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
931 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700932
Raj Kamal389d6e32014-08-04 14:43:24 +0530933 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800934 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530935 }
936
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800937 if(!postHeuristicsHandling(ctx, list)) {
938 ALOGD_IF(isDebug(), "post heuristic handling failed");
939 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700940 return false;
941 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700942 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
943 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700944 return true;
945}
946
Sushil Chauhandefd3522014-05-13 18:17:12 -0700947/* Full MDP Composition with Peripheral Tiny Overlap Removal.
948 * MDP bandwidth limitations can be avoided, if the overlap region
949 * covered by the smallest layer at a higher z-order, gets composed
950 * by Copybit on a render buffer, which can be queued to MDP.
951 */
952bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
953 hwc_display_contents_1_t* list) {
954
955 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700956 // PTOR does not qualify when there are layers dropped, but if
957 // dropped layer is only a cursor, PTOR could qualify
958 const int numNonCursorLayers = numAppLayers - mCurrentFrame.dropCount;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959 const int stagesForMDP = min(sMaxPipesPerMixer,
960 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
961
962 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700963 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700964 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
965 return false;
966 }
967
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700968 // Frame level checks - consider PTOR in case of dropCount only if the cursor
969 // layer is dropped, otherwise bail out of PTOR
Sushil Chauhandefd3522014-05-13 18:17:12 -0700970 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700971 isYuvPresent(ctx, mDpy) || isSecurePresent(ctx, mDpy) ||
972 (mCurrentFrame.dropCount - (int)isCursorPresent(ctx, mDpy))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700973 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
974 return false;
975 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700976 // MDP comp checks
977 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700978 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700979 if(not isSupportedForMDPComp(ctx, layer)) {
980 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
981 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700982 }
983 }
984
Sushil Chauhandefd3522014-05-13 18:17:12 -0700985 /* We cannot use this composition mode, if:
986 1. A below layer needs scaling.
987 2. Overlap is not peripheral to display.
988 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700989 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700990 */
991
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700992 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
993 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
994 memset(overlapRect, 0, sizeof(overlapRect));
995 int layerPixelCount, minPixelCount = 0;
996 int numPTORLayersFound = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -0700997 for (int i = numNonCursorLayers - 1; (i >= 0 &&
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700998 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700999 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001000 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001001 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001002 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
1003 // PTOR layer should be peripheral and cannot have transform
1004 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
1005 has90Transform(layer)) {
1006 continue;
1007 }
1008 if((3 * (layerPixelCount + minPixelCount)) >
1009 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
1010 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
1011 continue;
1012 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001013 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001014 for (int j = i-1; j >= 0; j--) {
1015 // Check if the layers below this layer qualifies for PTOR comp
1016 hwc_layer_1_t* layer = &list->hwLayers[j];
1017 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001018 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001019 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001020 if (isValidRect(getIntersection(dispFrame, disFrame))) {
1021 if (has90Transform(layer) || needsScaling(layer)) {
1022 found = false;
1023 break;
1024 }
1025 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001026 }
1027 }
1028 // Store the minLayer Index
1029 if(found) {
1030 minLayerIndex[numPTORLayersFound] = i;
1031 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1032 minPixelCount += layerPixelCount;
1033 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001034 }
1035 }
1036
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001037 // No overlap layers
1038 if (!numPTORLayersFound)
1039 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001040
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001041 // Store the displayFrame and the sourceCrops of the layers
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001042 hwc_rect_t displayFrame[numNonCursorLayers];
1043 hwc_rect_t sourceCrop[numNonCursorLayers];
1044 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001045 hwc_layer_1_t* layer = &list->hwLayers[i];
1046 displayFrame[i] = layer->displayFrame;
1047 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001048 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001049
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301050 /**
1051 * It's possible that 2 PTOR layers might have overlapping.
1052 * In such case, remove the intersection(again if peripheral)
1053 * from the lower PTOR layer to avoid overlapping.
1054 * If intersection is not on peripheral then compromise
1055 * by reducing number of PTOR layers.
1056 **/
1057 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1058 if(isValidRect(commonRect)) {
1059 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1060 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1061 }
1062
1063 ctx->mPtorInfo.count = numPTORLayersFound;
1064 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1065 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1066 }
1067
1068 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1069 // reset PTOR
1070 ctx->mPtorInfo.count = 0;
1071 if(isValidRect(commonRect)) {
1072 // If PTORs are intersecting restore displayframe of PTOR[1]
1073 // before returning, as we have modified it above.
1074 list->hwLayers[minLayerIndex[1]].displayFrame =
1075 displayFrame[minLayerIndex[1]];
1076 }
1077 return false;
1078 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001079 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1080 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1081
Xu Yangcda012c2014-07-30 21:57:21 +08001082 // Store the blending mode, planeAlpha, and transform of PTOR layers
1083 int32_t blending[numPTORLayersFound];
1084 uint8_t planeAlpha[numPTORLayersFound];
1085 uint32_t transform[numPTORLayersFound];
1086
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001087 for(int j = 0; j < numPTORLayersFound; j++) {
1088 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001089
1090 // Update src crop of PTOR layer
1091 hwc_layer_1_t* layer = &list->hwLayers[index];
1092 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1093 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1094 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1095 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1096
1097 // Store & update w, h, format of PTOR layer
1098 private_handle_t *hnd = (private_handle_t *)layer->handle;
1099 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1100 layerWhf[j] = whf;
1101 hnd->width = renderBuf->width;
1102 hnd->height = renderBuf->height;
1103 hnd->format = renderBuf->format;
1104
Xu Yangcda012c2014-07-30 21:57:21 +08001105 // Store & update blending mode, planeAlpha and transform of PTOR layer
1106 blending[j] = layer->blending;
1107 planeAlpha[j] = layer->planeAlpha;
1108 transform[j] = layer->transform;
1109 layer->blending = HWC_BLENDING_NONE;
1110 layer->planeAlpha = 0xFF;
1111 layer->transform = 0;
1112
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001113 // Remove overlap from crop & displayFrame of below layers
1114 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001115 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001116 if(!isValidRect(getIntersection(layer->displayFrame,
1117 overlapRect[j]))) {
1118 continue;
1119 }
1120 // Update layer attributes
1121 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1122 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301123 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001124 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1125 layer->transform);
1126 layer->sourceCropf.left = (float)srcCrop.left;
1127 layer->sourceCropf.top = (float)srcCrop.top;
1128 layer->sourceCropf.right = (float)srcCrop.right;
1129 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1130 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001131 }
1132
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001133 mCurrentFrame.mdpCount = numNonCursorLayers;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001134 mCurrentFrame.fbCount = 0;
1135 mCurrentFrame.fbZ = -1;
1136
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001137 for (int j = 0; j < numNonCursorLayers; j++) {
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301138 if(isValidRect(list->hwLayers[j].displayFrame)) {
1139 mCurrentFrame.isFBComposed[j] = false;
1140 } else {
1141 mCurrentFrame.mdpCount--;
1142 mCurrentFrame.drop[j] = true;
1143 }
1144 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001145
1146 bool result = postHeuristicsHandling(ctx, list);
1147
1148 // Restore layer attributes
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001149 for(int i = 0; i < numNonCursorLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001150 hwc_layer_1_t* layer = &list->hwLayers[i];
1151 layer->displayFrame = displayFrame[i];
1152 layer->sourceCropf.left = (float)sourceCrop[i].left;
1153 layer->sourceCropf.top = (float)sourceCrop[i].top;
1154 layer->sourceCropf.right = (float)sourceCrop[i].right;
1155 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1156 }
1157
Xu Yangcda012c2014-07-30 21:57:21 +08001158 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001159 for (int i = 0; i < numPTORLayersFound; i++) {
1160 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001161 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001162 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1163 hnd->width = layerWhf[i].w;
1164 hnd->height = layerWhf[i].h;
1165 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001166 layer->blending = blending[i];
1167 layer->planeAlpha = planeAlpha[i];
1168 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001169 }
1170
Sushil Chauhandefd3522014-05-13 18:17:12 -07001171 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001172 // reset PTOR
1173 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001174 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001175 } else {
1176 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1177 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001178 }
1179
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001180 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1181 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001182 return result;
1183}
1184
Saurabh Shahaa236822013-04-24 18:07:26 -07001185bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1186{
radhakrishnac3198ff2015-03-10 17:10:02 +05301187 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1188 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001189 return false;
1190 }
1191
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001192 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301193 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1194 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001195 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001196 cacheBasedComp(ctx, list);
1197 } else {
1198 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001199 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001200 }
1201
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001202 return ret;
1203}
1204
1205bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1206 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001207 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1208 return false;
1209
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001210 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001211 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001212 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001213
1214 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1215 for(int i = 0; i < numAppLayers; i++) {
1216 if(!mCurrentFrame.isFBComposed[i]) {
1217 hwc_layer_1_t* layer = &list->hwLayers[i];
1218 if(not isSupportedForMDPComp(ctx, layer)) {
1219 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1220 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001221 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001222 return false;
1223 }
1224 }
1225 }
1226
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001227 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001228 /* mark secure RGB layers for MDP comp */
1229 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301230 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001231 if(!ret) {
1232 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001233 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001234 return false;
1235 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001236
1237 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001238
Raj Kamal389d6e32014-08-04 14:43:24 +05301239 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001240 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301241 }
1242
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001243 if(!postHeuristicsHandling(ctx, list)) {
1244 ALOGD_IF(isDebug(), "post heuristic handling failed");
1245 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001246 return false;
1247 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001248 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1249 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001250
Saurabh Shahaa236822013-04-24 18:07:26 -07001251 return true;
1252}
1253
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001254bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001255 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001256 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1257 return false;
1258
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001259 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001260 return false;
1261 }
1262
Saurabh Shahb772ae32013-11-18 15:40:02 -08001263 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001264 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1265 const int stagesForMDP = min(sMaxPipesPerMixer,
1266 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001267
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001268 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1269 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1270 int lastMDPSupportedIndex = numAppLayers;
1271 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001272
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001273 //Find the minimum MDP batch size
1274 for(int i = 0; i < numAppLayers;i++) {
1275 if(mCurrentFrame.drop[i]) {
1276 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001277 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001278 }
1279 hwc_layer_1_t* layer = &list->hwLayers[i];
1280 if(not isSupportedForMDPComp(ctx, layer)) {
1281 lastMDPSupportedIndex = i;
1282 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1283 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001284 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001285 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001286 }
1287
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001288 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1289 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1290 mCurrentFrame.dropCount);
1291
1292 //Start at a point where the fb batch should at least have 2 layers, for
1293 //this mode to be justified.
1294 while(fbBatchSize < 2) {
1295 ++fbBatchSize;
1296 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001297 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001298
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001299 //If there are no layers for MDP, this mode doesnt make sense.
1300 if(mdpBatchSize < 1) {
1301 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1302 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001303 return false;
1304 }
1305
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001306 mCurrentFrame.reset(numAppLayers);
1307
1308 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1309 while(mdpBatchSize > 0) {
1310 //Mark layers for MDP comp
1311 int mdpBatchLeft = mdpBatchSize;
1312 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1313 if(mCurrentFrame.drop[i]) {
1314 continue;
1315 }
1316 mCurrentFrame.isFBComposed[i] = false;
1317 --mdpBatchLeft;
1318 }
1319
1320 mCurrentFrame.fbZ = mdpBatchSize;
1321 mCurrentFrame.fbCount = fbBatchSize;
1322 mCurrentFrame.mdpCount = mdpBatchSize;
1323
1324 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1325 __FUNCTION__, mdpBatchSize, fbBatchSize,
1326 mCurrentFrame.dropCount);
1327
1328 if(postHeuristicsHandling(ctx, list)) {
1329 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001330 __FUNCTION__);
1331 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1332 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001333 return true;
1334 }
1335
1336 reset(ctx);
1337 --mdpBatchSize;
1338 ++fbBatchSize;
1339 }
1340
1341 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001342}
1343
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001344bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301345 if(mDpy or isSecurePresent(ctx, mDpy) or
1346 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001347 return false;
1348 }
1349 return true;
1350}
1351
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001352bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1353 hwc_display_contents_1_t* list){
1354 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1355 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001356 isCursorPresent(ctx, mDpy) || !sIsPartialUpdateActive || mDpy) {
1357 // On Async position update, the ROI becomes invalid, hence disable PU
1358 // when cursor is present
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001359 return false;
1360 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001361 if(ctx->listStats[mDpy].secureUI)
1362 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001363 return true;
1364}
1365
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001366bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1367 hwc_display_contents_1_t* list) {
1368 const bool secureOnly = true;
1369 return videoOnlyComp(ctx, list, not secureOnly) or
1370 videoOnlyComp(ctx, list, secureOnly);
1371}
1372
1373bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001374 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001375 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1376 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301377
Saurabh Shahaa236822013-04-24 18:07:26 -07001378 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301379 if(!isSecurePresent(ctx, mDpy)) {
1380 /* Bail out if we are processing only secured video layers
1381 * and we dont have any */
1382 if(secureOnly) {
1383 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1384 return false;
1385 }
1386 /* No Idle fall back for secure video layers and if there is only
1387 * single layer being composed. */
1388 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1389 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1390 return false;
1391 }
1392 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001393
Saurabh Shahaa236822013-04-24 18:07:26 -07001394 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001395 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001396 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001397 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001398
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001399 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1400 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001401 return false;
1402 }
1403
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001404 if(mCurrentFrame.fbCount)
1405 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001406
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001407 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001408 adjustForSourceSplit(ctx, list);
1409 }
1410
1411 if(!postHeuristicsHandling(ctx, list)) {
1412 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301413 if(errno == ENOBUFS) {
1414 ALOGD_IF(isDebug(), "SMP Allocation failed");
1415 //On SMP allocation failure in video only comp add padding round
1416 ctx->isPaddingRound = true;
1417 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001418 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001419 return false;
1420 }
1421
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001422 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1423 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001424 return true;
1425}
1426
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001427/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1428bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1429 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001430 // Fall back to video only composition, if AIV video mode is enabled
1431 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001432 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1433 __FUNCTION__, mDpy);
1434 return false;
1435 }
1436
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001437 // No MDP composition for 3D
1438 if(needs3DComposition(ctx,mDpy))
1439 return false;
1440
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001441 const bool secureOnly = true;
1442 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1443 mdpOnlyLayersComp(ctx, list, secureOnly);
1444
1445}
1446
1447bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1448 hwc_display_contents_1_t* list, bool secureOnly) {
1449
1450 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1451 return false;
1452
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301453 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1454 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1455 /* Bail out if we are processing only secured video/ui layers
1456 * and we dont have any */
1457 if(secureOnly) {
1458 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1459 return false;
1460 }
1461 /* No Idle fall back for secure video/ui layers and if there is only
1462 * single layer being composed. */
1463 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1464 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1465 return false;
1466 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001467 }
1468
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001469 /* Bail out if we dont have any secure RGB layers */
1470 if (!ctx->listStats[mDpy].secureRGBCount) {
1471 reset(ctx);
1472 return false;
1473 }
1474
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001475 mCurrentFrame.reset(numAppLayers);
1476 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1477
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001478 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001479 /* mark secure RGB layers for MDP comp */
1480 updateSecureRGB(ctx, list);
1481
1482 if(mCurrentFrame.mdpCount == 0) {
1483 reset(ctx);
1484 return false;
1485 }
1486
1487 /* find the maximum batch of layers to be marked for framebuffer */
1488 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1489 if(!ret) {
1490 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1491 reset(ctx);
1492 return false;
1493 }
1494
1495 if(sEnableYUVsplit){
1496 adjustForSourceSplit(ctx, list);
1497 }
1498
1499 if(!postHeuristicsHandling(ctx, list)) {
1500 ALOGD_IF(isDebug(), "post heuristic handling failed");
1501 reset(ctx);
1502 return false;
1503 }
1504
1505 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1506 __FUNCTION__);
1507 return true;
1508}
1509
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001510/* Checks for conditions where YUV layers cannot be bypassed */
1511bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001512 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001513 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001514 return false;
1515 }
1516
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001517 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001518 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1519 return false;
1520 }
1521
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001522 if(isSecuring(ctx, layer)) {
1523 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1524 return false;
1525 }
1526
Saurabh Shah4fdde762013-04-30 18:47:33 -07001527 if(!isValidDimension(ctx, layer)) {
1528 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1529 __FUNCTION__);
1530 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001531 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001532
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001533 if(layer->planeAlpha < 0xFF) {
1534 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1535 in video only mode",
1536 __FUNCTION__);
1537 return false;
1538 }
1539
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001540 return true;
1541}
1542
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001543/* Checks for conditions where Secure RGB layers cannot be bypassed */
1544bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1545 if(isSkipLayer(layer)) {
1546 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1547 __FUNCTION__, mDpy);
1548 return false;
1549 }
1550
1551 if(isSecuring(ctx, layer)) {
1552 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1553 return false;
1554 }
1555
1556 if(not isSupportedForMDPComp(ctx, layer)) {
1557 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1558 __FUNCTION__);
1559 return false;
1560 }
1561 return true;
1562}
1563
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301564/* starts at fromIndex and check for each layer to find
1565 * if it it has overlapping with any Updating layer above it in zorder
1566 * till the end of the batch. returns true if it finds any intersection */
1567bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1568 int fromIndex, int toIndex) {
1569 for(int i = fromIndex; i < toIndex; i++) {
1570 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1571 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1572 return false;
1573 }
1574 }
1575 }
1576 return true;
1577}
1578
1579/* Checks if given layer at targetLayerIndex has any
1580 * intersection with all the updating layers in beween
1581 * fromIndex and toIndex. Returns true if it finds intersectiion */
1582bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1583 int fromIndex, int toIndex, int targetLayerIndex) {
1584 for(int i = fromIndex; i <= toIndex; i++) {
1585 if(!mCurrentFrame.isFBComposed[i]) {
1586 if(areLayersIntersecting(&list->hwLayers[i],
1587 &list->hwLayers[targetLayerIndex])) {
1588 return true;
1589 }
1590 }
1591 }
1592 return false;
1593}
1594
1595int MDPComp::getBatch(hwc_display_contents_1_t* list,
1596 int& maxBatchStart, int& maxBatchEnd,
1597 int& maxBatchCount) {
1598 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301599 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001600 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301601 while (i < mCurrentFrame.layerCount) {
1602 int batchCount = 0;
1603 int batchStart = i;
1604 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001605 /* Adjust batch Z order with the dropped layers so far */
1606 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301607 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301608 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301609 while(i < mCurrentFrame.layerCount) {
1610 if(!mCurrentFrame.isFBComposed[i]) {
1611 if(!batchCount) {
1612 i++;
1613 break;
1614 }
1615 updatingLayersAbove++;
1616 i++;
1617 continue;
1618 } else {
1619 if(mCurrentFrame.drop[i]) {
1620 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001621 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301622 continue;
1623 } else if(updatingLayersAbove <= 0) {
1624 batchCount++;
1625 batchEnd = i;
1626 i++;
1627 continue;
1628 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1629
1630 // We have a valid updating layer already. If layer-i not
1631 // have overlapping with all updating layers in between
1632 // batch-start and i, then we can add layer i to batch.
1633 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1634 batchCount++;
1635 batchEnd = i;
1636 i++;
1637 continue;
1638 } else if(canPushBatchToTop(list, batchStart, i)) {
1639 //If All the non-updating layers with in this batch
1640 //does not have intersection with the updating layers
1641 //above in z-order, then we can safely move the batch to
1642 //higher z-order. Increment fbZ as it is moving up.
1643 if( firstZReverseIndex < 0) {
1644 firstZReverseIndex = i;
1645 }
1646 batchCount++;
1647 batchEnd = i;
1648 fbZ += updatingLayersAbove;
1649 i++;
1650 updatingLayersAbove = 0;
1651 continue;
1652 } else {
1653 //both failed.start the loop again from here.
1654 if(firstZReverseIndex >= 0) {
1655 i = firstZReverseIndex;
1656 }
1657 break;
1658 }
1659 }
1660 }
1661 }
1662 if(batchCount > maxBatchCount) {
1663 maxBatchCount = batchCount;
1664 maxBatchStart = batchStart;
1665 maxBatchEnd = batchEnd;
1666 fbZOrder = fbZ;
1667 }
1668 }
1669 return fbZOrder;
1670}
1671
1672bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1673 hwc_display_contents_1_t* list) {
1674 /* Idea is to keep as many non-updating(cached) layers in FB and
1675 * send rest of them through MDP. This is done in 2 steps.
1676 * 1. Find the maximum contiguous batch of non-updating layers.
1677 * 2. See if we can improve this batch size for caching by adding
1678 * opaque layers around the batch, if they don't have
1679 * any overlapping with the updating layers in between.
1680 * NEVER mark an updating layer for caching.
1681 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001682
1683 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001684 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001685 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301686 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001687
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001688 /* Nothing is cached. No batching needed */
1689 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001690 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001691 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001692
1693 /* No MDP comp layers, try to use other comp modes */
1694 if(mCurrentFrame.mdpCount == 0) {
1695 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001696 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001697
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301698 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001699
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301700 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001701 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001702 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001703 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301704 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001705 if(!mCurrentFrame.drop[i]){
1706 //If an unsupported layer is being attempted to
1707 //be pulled out we should fail
1708 if(not isSupportedForMDPComp(ctx, layer)) {
1709 return false;
1710 }
1711 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001712 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001713 }
1714 }
1715
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301716 // update the frame data
1717 mCurrentFrame.fbZ = fbZ;
1718 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001719 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001720 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001721
1722 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301723 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001724
1725 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001726}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001727
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001728void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001729 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001730 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001731 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001732
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001733 for(int i = 0; i < numAppLayers; i++) {
1734 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001735 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001736 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001737 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001738 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001739 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001740 }
1741 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001742
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001743 frame.fbCount = fbCount;
1744 frame.mdpCount = frame.layerCount - frame.fbCount
1745 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001746
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001747 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1748 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001749}
1750
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001751// drop other non-AIV layers from external display list.
1752void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001753 hwc_display_contents_1_t* list) {
1754 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1755 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001756 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001757 mCurrentFrame.dropCount++;
1758 mCurrentFrame.drop[i] = true;
1759 }
1760 }
1761 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1762 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1763 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1764 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1765 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1766 mCurrentFrame.dropCount);
1767}
1768
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001769void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001770 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001771 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1772 for(int index = 0;index < nYuvCount; index++){
1773 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1774 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1775
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001776 if(mCurrentFrame.drop[nYuvIndex]) {
1777 continue;
1778 }
1779
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001780 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001781 if(!frame.isFBComposed[nYuvIndex]) {
1782 frame.isFBComposed[nYuvIndex] = true;
1783 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 }
1785 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001786 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001787 private_handle_t *hnd = (private_handle_t *)layer->handle;
1788 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001789 frame.isFBComposed[nYuvIndex] = false;
1790 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001791 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001792 }
1793 }
1794 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001795
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001796 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1797 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001798}
1799
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001800void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1801 hwc_display_contents_1_t* list) {
1802 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1803 for(int index = 0;index < nSecureRGBCount; index++){
1804 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1805 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1806
1807 if(!isSecureRGBDoable(ctx, layer)) {
1808 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1809 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1810 mCurrentFrame.fbCount++;
1811 }
1812 } else {
1813 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1814 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1815 mCurrentFrame.fbCount--;
1816 }
1817 }
1818 }
1819
1820 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1821 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1822 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1823 mCurrentFrame.fbCount);
1824}
1825
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001826hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1827 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001828 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001829
1830 /* Update only the region of FB needed for composition */
1831 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1832 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1833 hwc_layer_1_t* layer = &list->hwLayers[i];
1834 hwc_rect_t dst = layer->displayFrame;
1835 fbRect = getUnion(fbRect, dst);
1836 }
1837 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001838 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001839 return fbRect;
1840}
1841
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001842bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1843 hwc_display_contents_1_t* list) {
1844
1845 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001846 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001847 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1848 return false;
1849 }
1850
1851 //Limitations checks
1852 if(!hwLimitationsCheck(ctx, list)) {
1853 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1854 return false;
1855 }
1856
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001857 //Configure framebuffer first if applicable
1858 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001859 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001860 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1861 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001862 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1863 __FUNCTION__);
1864 return false;
1865 }
1866 }
1867
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001868 mCurrentFrame.map();
1869
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001870 if(!allocLayerPipes(ctx, list)) {
1871 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001872 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001873 }
1874
1875 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001876 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001877 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001878 int mdpIndex = mCurrentFrame.layerToMDP[index];
1879 hwc_layer_1_t* layer = &list->hwLayers[index];
1880
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301881 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1882 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1883 mdpNextZOrder++;
1884 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001885 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1886 cur_pipe->zOrder = mdpNextZOrder++;
1887
radhakrishnac9a67412013-09-25 17:40:42 +05301888 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301889 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301890 if(configure4k2kYuv(ctx, layer,
1891 mCurrentFrame.mdpToLayer[mdpIndex])
1892 != 0 ){
1893 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1894 for layer %d",__FUNCTION__, index);
1895 return false;
1896 }
1897 else{
1898 mdpNextZOrder++;
1899 }
1900 continue;
1901 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001902 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1903 mdpNextZOrder++;
1904 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001905 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1906 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301907 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001908 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001909 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001910 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001911 }
1912
Saurabh Shaha36be922013-12-16 18:18:39 -08001913 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1914 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1915 ,__FUNCTION__, mDpy);
1916 return false;
1917 }
1918
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001919 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001920 return true;
1921}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001922
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001923bool MDPComp::resourceCheck(hwc_context_t* ctx,
1924 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001925 const bool fbUsed = mCurrentFrame.fbCount;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07001926 int cursorInUse = 0;
1927 if(mDpy == HWC_DISPLAY_PRIMARY) {
1928 // check if cursor is in use for primary
1929 cursorInUse = HWCursor::getInstance()->isCursorSet();
1930 }
1931 int maxStages = qdutils::MDPVersion::getInstance().getBlendStages();
1932 // HW Cursor needs one blending stage, account for that in the check below
1933 // On high end targets(8994) has 8 blending stages, HAL is configured to use < 8.
1934 // Make use of the remaining stages for HW Cursor so that the composition
1935 // strategy would not fail due to this limitation.
1936 if (maxStages > sMaxPipesPerMixer) {
1937 cursorInUse = 0;
1938 }
1939 if(mCurrentFrame.mdpCount > (sMaxPipesPerMixer - fbUsed - cursorInUse)) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001940 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1941 return false;
1942 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001943
1944 //Will benefit cases where a video has non-updating background.
1945 if((mDpy > HWC_DISPLAY_PRIMARY) and
1946 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1947 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1948 return false;
1949 }
1950
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001951 // Init rotCount to number of rotate sessions used by other displays
1952 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1953 // Count the number of rotator sessions required for current display
1954 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1955 if(!mCurrentFrame.isFBComposed[index]) {
1956 hwc_layer_1_t* layer = &list->hwLayers[index];
1957 private_handle_t *hnd = (private_handle_t *)layer->handle;
1958 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1959 rotCount++;
1960 }
1961 }
1962 }
1963 // if number of layers to rotate exceeds max rotator sessions, bail out.
1964 if(rotCount > RotMgr::MAX_ROT_SESS) {
1965 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1966 __FUNCTION__, mDpy);
1967 return false;
1968 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001969 return true;
1970}
1971
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301972bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1973 hwc_display_contents_1_t* list) {
1974
1975 //A-family hw limitation:
1976 //If a layer need alpha scaling, MDP can not support.
1977 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1978 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1979 if(!mCurrentFrame.isFBComposed[i] &&
1980 isAlphaScaled( &list->hwLayers[i])) {
1981 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1982 return false;
1983 }
1984 }
1985 }
1986
1987 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1988 //If multiple layers requires downscaling and also they are overlapping
1989 //fall back to GPU since MDSS can not handle it.
1990 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1991 qdutils::MDPVersion::getInstance().is8x26()) {
1992 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1993 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1994 if(!mCurrentFrame.isFBComposed[i] &&
1995 isDownscaleRequired(botLayer)) {
1996 //if layer-i is marked for MDP and needs downscaling
1997 //check if any MDP layer on top of i & overlaps with layer-i
1998 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1999 hwc_layer_1_t* topLayer = &list->hwLayers[j];
2000 if(!mCurrentFrame.isFBComposed[j] &&
2001 isDownscaleRequired(topLayer)) {
2002 hwc_rect_t r = getIntersection(botLayer->displayFrame,
2003 topLayer->displayFrame);
2004 if(isValidRect(r))
2005 return false;
2006 }
2007 }
2008 }
2009 }
2010 }
2011 return true;
2012}
2013
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002014static bool validForCursor(hwc_context_t* ctx, int dpy, hwc_layer_1_t* layer) {
2015 private_handle_t *hnd = (private_handle_t *)layer->handle;
2016 hwc_rect dst = layer->displayFrame;
2017 hwc_rect src = integerizeSourceCrop(layer->sourceCropf);
2018 int srcW = src.right - src.left;
2019 int srcH = src.bottom - src.top;
2020 int dstW = dst.right - dst.left;
2021 int dstH = dst.bottom - dst.top;
2022 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
2023 uint32_t maxCursorSize = mdpVersion.getMaxCursorSize();
2024 uint32_t numHwCursors = mdpVersion.getCursorPipes();
2025 bool primarySplit = isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY);
2026 uint32_t cursorPipesNeeded = 1; // One cursor pipe needed(default)
2027 bool ret = false;
2028
2029 if(dpy > HWC_DISPLAY_PRIMARY) {
2030 // Cursor not supported on secondary displays, as it involves scaling
2031 // in most of the cases
2032 return false;
2033 } else if (isSkipLayer(layer)) {
2034 return false;
2035 // Checks for HW limitation
2036 } else if (numHwCursors == 0 || maxCursorSize <= 0) {
2037 return false;
2038 } else if (needsScaling(layer)) {
2039 return false;
2040 } else if (layer->transform != 0) {
2041 return false;
2042 } else if (hnd->format != HAL_PIXEL_FORMAT_RGBA_8888) {
2043 return false;
2044 } else if (srcW > (int)maxCursorSize || srcH > (int)maxCursorSize) {
2045 return false;
2046 }
2047
2048 if (isDisplaySplit(ctx, dpy) && !mdpVersion.isSrcSplit()) {
2049 // In case of split display with no srcSplit, the driver allocates two
2050 // pipes to support async position update across mixers, hence
2051 // need to account for that here.
2052 cursorPipesNeeded = 2;
2053 }
2054 if (cursorPipesNeeded <= numHwCursors) {
2055 ret = true;
2056 }
2057 return ret;
2058}
2059
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002060// Checks only if videos or single layer(RGB) is updating
2061// which is used for setting dynamic fps or perf hint for single
2062// layer video playback
2063bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
2064 hwc_display_contents_1_t* list) {
2065 bool support = false;
2066 FrameInfo frame;
2067 frame.reset(mCurrentFrame.layerCount);
2068 memset(&frame.drop, 0, sizeof(frame.drop));
2069 frame.dropCount = 0;
2070 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
2071 updateLayerCache(ctx, list, frame);
2072 updateYUV(ctx, list, false /*secure only*/, frame);
2073 // There are only updating YUV layers or there is single RGB
2074 // Layer(Youtube)
2075 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2076 (frame.layerCount == 1)) {
2077 support = true;
2078 }
2079 return support;
2080}
2081
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302082void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2083 //For primary display, set the dynamic refreshrate
2084 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
2085 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302086 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2087 MDPVersion& mdpHw = MDPVersion::getInstance();
2088 if(sIdleFallBack) {
2089 //Set minimum panel refresh rate during idle timeout
2090 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002091 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302092 //Set the new fresh rate, if there is only one updating YUV layer
2093 //or there is one single RGB layer with this request
2094 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2095 }
2096 setRefreshRate(ctx, mDpy, refreshRate);
2097 }
2098}
2099
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002100int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002101 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002102 char property[PROPERTY_VALUE_MAX];
2103
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002104 if(!list) {
2105 ALOGE("%s: Invalid list", __FUNCTION__);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302106 mCachedFrame.reset();
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002107 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302108 return -1;
2109 }
2110
2111 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002112 if(mDpy == HWC_DISPLAY_PRIMARY) {
2113 sSimulationFlags = 0;
2114 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2115 int currentFlags = atoi(property);
2116 if(currentFlags != sSimulationFlags) {
2117 sSimulationFlags = currentFlags;
2118 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2119 sSimulationFlags, sSimulationFlags);
2120 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002121 }
2122 }
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002123
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302124 //reset old data
2125 mCurrentFrame.reset(numLayers);
2126 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2127 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002128 mCurrentFrame.hwCursorIndex = -1;
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302129
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302130 //Do not cache the information for next draw cycle.
2131 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2132 ALOGI("%s: Unsupported layer count for mdp composition",
2133 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002134 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302135#ifdef DYNAMIC_FPS
2136 setDynRefreshRate(ctx, list);
2137#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002138 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002139 return -1;
2140 }
2141
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002142 // Detect the start of animation and fall back to GPU only once to cache
2143 // all the layers in FB and display FB content untill animation completes.
2144 if(ctx->listStats[mDpy].isDisplayAnimating) {
2145 mCurrentFrame.needsRedraw = false;
2146 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2147 mCurrentFrame.needsRedraw = true;
2148 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2149 }
2150 setMDPCompLayerFlags(ctx, list);
2151 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302152#ifdef DYNAMIC_FPS
2153 setDynRefreshRate(ctx, list);
2154#endif
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002155 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002156 ret = -1;
2157 return ret;
2158 } else {
2159 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2160 }
2161
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302162 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2163 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2164
2165 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2166 mCurrentFrame.needsRedraw = false;
2167 setMDPCompLayerFlags(ctx, list);
2168 mCachedFrame.updateCounts(mCurrentFrame);
2169#ifdef DYNAMIC_FPS
2170 setDynRefreshRate(ctx, list);
2171#endif
2172 return -1;
2173
2174 }
2175
Saurabh Shahb39f8152013-08-22 10:21:44 -07002176 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002177 if(isFrameDoable(ctx)) {
2178 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002179 // if AIV Video mode is enabled, drop all non AIV layers from the
2180 // external display list.
2181 if(ctx->listStats[mDpy].mAIVVideoMode) {
2182 dropNonAIVLayers(ctx, list);
2183 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002184
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002185 // Configure the cursor if present
2186 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2187 if(ctx->listStats[mDpy].cursorLayerPresent &&
2188 validForCursor(ctx, mDpy, &(list->hwLayers[topIndex]))) {
2189 if(configHwCursor(ctx->dpyAttr[mDpy].fd, mDpy,
2190 &(list->hwLayers[topIndex]))) {
2191 // As cursor is configured, mark that layer as dropped, so that
2192 // it wont be considered for composition by other strategies.
2193 mCurrentFrame.hwCursorIndex = topIndex;
2194 mCurrentFrame.drop[topIndex] = true;
2195 mCurrentFrame.dropCount++;
2196 }
2197 } else {
2198 // Release the hw cursor
2199 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
2200 }
2201
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002202 // if tryFullFrame fails, try to push all video and secure RGB layers
2203 // to MDP for composition.
2204 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002205 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302206 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002207 setMDPCompLayerFlags(ctx, list);
2208 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002209 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002210 reset(ctx);
2211 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2212 mCurrentFrame.dropCount = 0;
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002213 // Check if cursor is in use for primary and mark accordingly
2214 if(!mDpy && HWCursor::getInstance()->isCursorSet()) {
2215 int topIndex = ctx->listStats[mDpy].numAppLayers - 1;
2216 hwc_layer_1_t *layer = &(list->hwLayers[topIndex]);
2217 layer->compositionType = HWC_CURSOR_OVERLAY;
2218 }
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002219 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002220 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2221 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002222 }
2223 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302224 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2225 enablePartialUpdateForMDP3) {
2226 generateROI(ctx, list);
2227 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2228 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2229 }
2230 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002231 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2232 __FUNCTION__);
Arun Kumar K.R00b84792015-03-27 11:28:36 -07002233 // Release the hw cursor
2234 freeHwCursor(ctx->dpyAttr[mDpy].fd, mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002235 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002236 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002237
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002238 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002239 ALOGD("GEOMETRY change: %d",
2240 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002241 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002242 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002243 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002244 }
2245
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002246#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302247 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002248#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002249 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002250
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002251 mCachedFrame.cacheAll(list);
2252 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002253 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002254}
2255
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002256bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302257
2258 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302259 int mdpIndex = mCurrentFrame.layerToMDP[index];
2260 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2261 info.pipeInfo = new MdpYUVPipeInfo;
2262 info.rot = NULL;
2263 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302264
2265 pipe_info.lIndex = ovutils::OV_INVALID;
2266 pipe_info.rIndex = ovutils::OV_INVALID;
2267
Saurabh Shahc62f3982014-03-05 14:28:26 -08002268 Overlay::PipeSpecs pipeSpecs;
2269 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2270 pipeSpecs.needsScaling = true;
2271 pipeSpecs.dpy = mDpy;
2272 pipeSpecs.fb = false;
2273
2274 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302275 if(pipe_info.lIndex == ovutils::OV_INVALID){
2276 bRet = false;
2277 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2278 __FUNCTION__);
2279 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002280 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302281 if(pipe_info.rIndex == ovutils::OV_INVALID){
2282 bRet = false;
2283 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2284 __FUNCTION__);
2285 }
2286 return bRet;
2287}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002288
2289int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2290 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002291 if (ctx->mPtorInfo.isActive()) {
2292 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002293 if (fd < 0) {
2294 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002295 }
2296 }
2297 return fd;
2298}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002299//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002300
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002301void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302302 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002303 //If 4k2k Yuv layer split is possible, and if
2304 //fbz is above 4k2k layer, increment fb zorder by 1
2305 //as we split 4k2k layer and increment zorder for right half
2306 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002307 if(!ctx)
2308 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002309 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302310 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2311 index++) {
2312 if(!mCurrentFrame.isFBComposed[index]) {
2313 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2314 mdpNextZOrder++;
2315 }
2316 mdpNextZOrder++;
2317 hwc_layer_1_t* layer = &list->hwLayers[index];
2318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302319 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302320 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2321 mCurrentFrame.fbZ += 1;
2322 mdpNextZOrder++;
2323 //As we split 4kx2k yuv layer and program to 2 VG pipes
2324 //(if available) increase mdpcount by 1.
2325 mCurrentFrame.mdpCount++;
2326 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002327 }
2328 }
2329 }
radhakrishnac9a67412013-09-25 17:40:42 +05302330}
2331
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002332/*
2333 * Configures pipe(s) for MDP composition
2334 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002335int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002336 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002337 MdpPipeInfoNonSplit& mdp_info =
2338 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302339 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002340 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002341 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002342
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002343 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2344 __FUNCTION__, layer, zOrder, dest);
2345
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002346 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002347 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002348}
2349
Saurabh Shah88e4d272013-09-03 13:31:29 -07002350bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002351 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002352 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2353 formatType++) {
2354 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
2355 if(mCurrentFrame.isFBComposed[index]) continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002356
Saurabh Shah8cc77712015-03-31 10:48:51 -07002357 hwc_layer_1_t* layer = &list->hwLayers[index];
2358 private_handle_t *hnd = (private_handle_t *)layer->handle;
2359 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
radhakrishnac9a67412013-09-25 17:40:42 +05302360 continue;
Saurabh Shah8cc77712015-03-31 10:48:51 -07002361 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
2362 continue;
2363
2364 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2365 if(allocSplitVGPipes(ctx, index)){
2366 continue;
2367 }
radhakrishnac9a67412013-09-25 17:40:42 +05302368 }
radhakrishnac9a67412013-09-25 17:40:42 +05302369
Saurabh Shah8cc77712015-03-31 10:48:51 -07002370 int mdpIndex = mCurrentFrame.layerToMDP[index];
2371 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2372 info.pipeInfo = new MdpPipeInfoNonSplit;
2373 info.rot = NULL;
2374 MdpPipeInfoNonSplit& pipe_info =
2375 *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002376
Saurabh Shah8cc77712015-03-31 10:48:51 -07002377 Overlay::PipeSpecs pipeSpecs;
2378 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2379 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2380 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2381 (qdutils::MDPVersion::getInstance().is8x26() and
2382 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2383 pipeSpecs.dpy = mDpy;
2384 pipeSpecs.fb = false;
2385 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002386
Saurabh Shah8cc77712015-03-31 10:48:51 -07002387 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahc62f3982014-03-05 14:28:26 -08002388
Saurabh Shah8cc77712015-03-31 10:48:51 -07002389 if(pipe_info.index == ovutils::OV_INVALID) {
2390 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2391 "format type %d", __FUNCTION__, index, formatType);
2392 return false;
2393 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002394 }
2395 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002396 return true;
2397}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002398
radhakrishnac9a67412013-09-25 17:40:42 +05302399int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2400 PipeLayerPair& PipeLayerPair) {
2401 MdpYUVPipeInfo& mdp_info =
2402 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2403 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302404 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302405 eDest lDest = mdp_info.lIndex;
2406 eDest rDest = mdp_info.rIndex;
2407
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002408 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302409 lDest, rDest, &PipeLayerPair.rot);
2410}
2411
Saurabh Shah88e4d272013-09-03 13:31:29 -07002412bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002413
Raj Kamal4393eaa2014-06-06 13:45:20 +05302414 if(!isEnabled() or !mModeOn) {
2415 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302416 return true;
2417 }
2418
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002419 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002420 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002421
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002422 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2423 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002424 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002425 if(mCurrentFrame.isFBComposed[i]) continue;
2426
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002427 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002428 private_handle_t *hnd = (private_handle_t *)layer->handle;
2429 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002430 if (!(layer->flags & HWC_COLOR_FILL)) {
2431 ALOGE("%s handle null", __FUNCTION__);
2432 return false;
2433 }
2434 // No PLAY for Color layer
2435 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2436 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002437 }
2438
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002439 int mdpIndex = mCurrentFrame.layerToMDP[i];
2440
Raj Kamal389d6e32014-08-04 14:43:24 +05302441 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302442 {
2443 MdpYUVPipeInfo& pipe_info =
2444 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2445 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2446 ovutils::eDest indexL = pipe_info.lIndex;
2447 ovutils::eDest indexR = pipe_info.rIndex;
2448 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302449 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302450 if(rot) {
2451 rot->queueBuffer(fd, offset);
2452 fd = rot->getDstMemId();
2453 offset = rot->getDstOffset();
2454 }
2455 if(indexL != ovutils::OV_INVALID) {
2456 ovutils::eDest destL = (ovutils::eDest)indexL;
2457 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2458 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2459 if (!ov.queueBuffer(fd, offset, destL)) {
2460 ALOGE("%s: queueBuffer failed for display:%d",
2461 __FUNCTION__, mDpy);
2462 return false;
2463 }
2464 }
2465
2466 if(indexR != ovutils::OV_INVALID) {
2467 ovutils::eDest destR = (ovutils::eDest)indexR;
2468 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2469 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2470 if (!ov.queueBuffer(fd, offset, destR)) {
2471 ALOGE("%s: queueBuffer failed for display:%d",
2472 __FUNCTION__, mDpy);
2473 return false;
2474 }
2475 }
2476 }
2477 else{
2478 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002479 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302480 ovutils::eDest dest = pipe_info.index;
2481 if(dest == ovutils::OV_INVALID) {
2482 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002483 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302484 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002485
radhakrishnac9a67412013-09-25 17:40:42 +05302486 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2487 continue;
2488 }
2489
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002490 int fd = hnd->fd;
2491 uint32_t offset = (uint32_t)hnd->offset;
2492 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2493 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002494 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002495 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002496 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002497 }
2498
radhakrishnac9a67412013-09-25 17:40:42 +05302499 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2500 using pipe: %d", __FUNCTION__, layer,
2501 hnd, dest );
2502
radhakrishnac9a67412013-09-25 17:40:42 +05302503 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2504 if(rot) {
2505 if(!rot->queueBuffer(fd, offset))
2506 return false;
2507 fd = rot->getDstMemId();
2508 offset = rot->getDstOffset();
2509 }
2510
2511 if (!ov.queueBuffer(fd, offset, dest)) {
2512 ALOGE("%s: queueBuffer failed for display:%d ",
2513 __FUNCTION__, mDpy);
2514 return false;
2515 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002516 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002517
2518 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002519 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002520 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002521}
2522
Saurabh Shah88e4d272013-09-03 13:31:29 -07002523//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002524
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002525void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302526 hwc_display_contents_1_t* list){
2527 //if 4kx2k yuv layer is totally present in either in left half
2528 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302529 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302530 if(mCurrentFrame.fbZ >= 0) {
2531 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2532 index++) {
2533 if(!mCurrentFrame.isFBComposed[index]) {
2534 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2535 mdpNextZOrder++;
2536 }
2537 mdpNextZOrder++;
2538 hwc_layer_1_t* layer = &list->hwLayers[index];
2539 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002540 if(isYUVSplitNeeded(hnd) ||
2541 (needs3DComposition(ctx,mDpy) &&
2542 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302543 hwc_rect_t dst = layer->displayFrame;
2544 if((dst.left > lSplit) || (dst.right < lSplit)) {
2545 mCurrentFrame.mdpCount += 1;
2546 }
2547 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2548 mCurrentFrame.fbZ += 1;
2549 mdpNextZOrder++;
2550 }
2551 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002552 }
radhakrishnac9a67412013-09-25 17:40:42 +05302553 }
2554}
2555
Saurabh Shah88e4d272013-09-03 13:31:29 -07002556bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002557 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002558
Saurabh Shahc62f3982014-03-05 14:28:26 -08002559 const int lSplit = getLeftSplit(ctx, mDpy);
2560 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002561 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002562 pipe_info.lIndex = ovutils::OV_INVALID;
2563 pipe_info.rIndex = ovutils::OV_INVALID;
2564
Saurabh Shahc62f3982014-03-05 14:28:26 -08002565 Overlay::PipeSpecs pipeSpecs;
2566 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2567 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2568 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2569 pipeSpecs.dpy = mDpy;
2570 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2571 pipeSpecs.fb = false;
2572
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002573 // Acquire pipe only for the updating half
2574 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2575 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2576
2577 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002578 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002579 if(pipe_info.lIndex == ovutils::OV_INVALID)
2580 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002581 }
2582
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002583 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002584 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2585 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002586 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002587 return false;
2588 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002589
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002590 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002591}
2592
Saurabh Shah88e4d272013-09-03 13:31:29 -07002593bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002594 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002595 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2596 formatType++) {
2597 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
2598 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002599
Saurabh Shah8cc77712015-03-31 10:48:51 -07002600 hwc_layer_1_t* layer = &list->hwLayers[index];
2601 private_handle_t *hnd = (private_handle_t *)layer->handle;
2602 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
2603 continue;
2604 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002605 continue;
2606
Saurabh Shah8cc77712015-03-31 10:48:51 -07002607 hwc_rect_t dst = layer->displayFrame;
2608 const int lSplit = getLeftSplit(ctx, mDpy);
2609 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2610 if((dst.left > lSplit)||(dst.right < lSplit)){
2611 if(allocSplitVGPipes(ctx, index)){
2612 continue;
2613 }
2614 }
2615 }
2616 //XXX: Check for forced 2D composition
2617 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2618 if(allocSplitVGPipes(ctx,index))
2619 continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002620
Saurabh Shah8cc77712015-03-31 10:48:51 -07002621 int mdpIndex = mCurrentFrame.layerToMDP[index];
2622 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2623 info.pipeInfo = new MdpPipeInfoSplit;
2624 info.rot = NULL;
2625 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
2626
2627 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2628 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2629 "format type %d", __FUNCTION__, index, formatType);
2630 return false;
2631 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002632 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002633 }
2634 return true;
2635}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002636
radhakrishnac9a67412013-09-25 17:40:42 +05302637int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2638 PipeLayerPair& PipeLayerPair) {
2639 const int lSplit = getLeftSplit(ctx, mDpy);
2640 hwc_rect_t dst = layer->displayFrame;
2641 if((dst.left > lSplit)||(dst.right < lSplit)){
2642 MdpYUVPipeInfo& mdp_info =
2643 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2644 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302645 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302646 eDest lDest = mdp_info.lIndex;
2647 eDest rDest = mdp_info.rIndex;
2648
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002649 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302650 lDest, rDest, &PipeLayerPair.rot);
2651 }
2652 else{
2653 return configure(ctx, layer, PipeLayerPair);
2654 }
2655}
2656
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002657/*
2658 * Configures pipe(s) for MDP composition
2659 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002660int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002661 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002662 MdpPipeInfoSplit& mdp_info =
2663 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002664 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302665 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002666 eDest lDest = mdp_info.lIndex;
2667 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002668
2669 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002670 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002671
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002672 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002673 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002674}
2675
Saurabh Shah88e4d272013-09-03 13:31:29 -07002676bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002677
Raj Kamal4393eaa2014-06-06 13:45:20 +05302678 if(!isEnabled() or !mModeOn) {
2679 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302680 return true;
2681 }
2682
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002683 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002684 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002685
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002686 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2687 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002688 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002689 if(mCurrentFrame.isFBComposed[i]) continue;
2690
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002691 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002692 private_handle_t *hnd = (private_handle_t *)layer->handle;
2693 if(!hnd) {
2694 ALOGE("%s handle null", __FUNCTION__);
2695 return false;
2696 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002697
2698 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2699 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002700 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002701
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002702 int mdpIndex = mCurrentFrame.layerToMDP[i];
2703
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002704 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2705 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302706 {
2707 MdpYUVPipeInfo& pipe_info =
2708 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2709 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2710 ovutils::eDest indexL = pipe_info.lIndex;
2711 ovutils::eDest indexR = pipe_info.rIndex;
2712 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302713 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302714 if(rot) {
2715 rot->queueBuffer(fd, offset);
2716 fd = rot->getDstMemId();
2717 offset = rot->getDstOffset();
2718 }
2719 if(indexL != ovutils::OV_INVALID) {
2720 ovutils::eDest destL = (ovutils::eDest)indexL;
2721 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2722 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2723 if (!ov.queueBuffer(fd, offset, destL)) {
2724 ALOGE("%s: queueBuffer failed for display:%d",
2725 __FUNCTION__, mDpy);
2726 return false;
2727 }
2728 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002729
radhakrishnac9a67412013-09-25 17:40:42 +05302730 if(indexR != ovutils::OV_INVALID) {
2731 ovutils::eDest destR = (ovutils::eDest)indexR;
2732 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2733 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2734 if (!ov.queueBuffer(fd, offset, destR)) {
2735 ALOGE("%s: queueBuffer failed for display:%d",
2736 __FUNCTION__, mDpy);
2737 return false;
2738 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002739 }
2740 }
radhakrishnac9a67412013-09-25 17:40:42 +05302741 else{
2742 MdpPipeInfoSplit& pipe_info =
2743 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2744 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002745
radhakrishnac9a67412013-09-25 17:40:42 +05302746 ovutils::eDest indexL = pipe_info.lIndex;
2747 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002748
radhakrishnac9a67412013-09-25 17:40:42 +05302749 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002750 uint32_t offset = (uint32_t)hnd->offset;
2751 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2752 if (!mDpy && (index != -1)) {
2753 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2754 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002755 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002756 }
radhakrishnac9a67412013-09-25 17:40:42 +05302757
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002758 if(ctx->mAD->draw(ctx, fd, offset)) {
2759 fd = ctx->mAD->getDstFd();
2760 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002761 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002762
radhakrishnac9a67412013-09-25 17:40:42 +05302763 if(rot) {
2764 rot->queueBuffer(fd, offset);
2765 fd = rot->getDstMemId();
2766 offset = rot->getDstOffset();
2767 }
2768
2769 //************* play left mixer **********
2770 if(indexL != ovutils::OV_INVALID) {
2771 ovutils::eDest destL = (ovutils::eDest)indexL;
2772 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2773 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2774 if (!ov.queueBuffer(fd, offset, destL)) {
2775 ALOGE("%s: queueBuffer failed for left mixer",
2776 __FUNCTION__);
2777 return false;
2778 }
2779 }
2780
2781 //************* play right mixer **********
2782 if(indexR != ovutils::OV_INVALID) {
2783 ovutils::eDest destR = (ovutils::eDest)indexR;
2784 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2785 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2786 if (!ov.queueBuffer(fd, offset, destR)) {
2787 ALOGE("%s: queueBuffer failed for right mixer",
2788 __FUNCTION__);
2789 return false;
2790 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002791 }
2792 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002793
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002794 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2795 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002796
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002797 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002798}
Saurabh Shahab47c692014-02-12 18:45:57 -08002799
2800//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002801
2802bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2803 hwc_display_contents_1_t* list) {
2804 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2805 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2806
2807 for(int i = numAppLayers - 1; i >= 0; i--) {
2808 if(!isValidRect(visibleRect)) {
2809 mCurrentFrame.drop[i] = true;
2810 mCurrentFrame.dropCount++;
2811 continue;
2812 }
2813
2814 const hwc_layer_1_t* layer = &list->hwLayers[i];
2815 hwc_rect_t dstRect = layer->displayFrame;
2816 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2817
2818 if(!isValidRect(res)) {
2819 mCurrentFrame.drop[i] = true;
2820 mCurrentFrame.dropCount++;
2821 } else {
2822 /* Reset frame ROI when any layer which needs scaling also needs ROI
2823 * cropping */
2824 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2825 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2826 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2827 mCurrentFrame.dropCount = 0;
2828 return false;
2829 }
2830
2831 /* deduct any opaque region from visibleRect */
2832 if (layer->blending == HWC_BLENDING_NONE &&
2833 layer->planeAlpha == 0xFF)
2834 visibleRect = deductRect(visibleRect, res);
2835 }
2836 }
2837 return true;
2838}
2839
2840/*
2841 * HW Limitation: ping pong split can always split the ping pong output
2842 * equally across two DSI's. So the ROI programmed should be of equal width
2843 * for both the halves
2844 */
2845void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2846 hwc_display_contents_1_t* list) {
2847 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2848
2849
2850 if(!canPartialUpdate(ctx, list))
2851 return;
2852
2853 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2854 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2855 (int)ctx->dpyAttr[mDpy].yres};
2856
2857 for(int index = 0; index < numAppLayers; index++ ) {
2858 hwc_layer_1_t* layer = &list->hwLayers[index];
2859
2860 // If we have a RGB layer which needs rotation, no partial update
2861 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2862 return;
2863
2864 if ((mCachedFrame.hnd[index] != layer->handle) ||
2865 isYuvBuffer((private_handle_t *)layer->handle)) {
2866 hwc_rect_t dst = layer->displayFrame;
2867 hwc_rect_t updatingRect = dst;
2868
2869#ifdef QCOM_BSP
2870 if(!needsScaling(layer) && !layer->transform)
2871 {
2872 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2873 int x_off = dst.left - src.left;
2874 int y_off = dst.top - src.top;
2875 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2876 }
2877#endif
2878
2879 roi = getUnion(roi, updatingRect);
2880 }
2881 }
2882
2883 /* No layer is updating. Still SF wants a refresh.*/
2884 if(!isValidRect(roi))
2885 return;
2886
2887 roi = expandROIFromMidPoint(roi, fullFrame);
2888
2889 hwc_rect lFrame = fullFrame;
2890 lFrame.right /= 2;
2891 hwc_rect lRoi = getIntersection(roi, lFrame);
2892
2893 // Align ROI coordinates to panel restrictions
2894 lRoi = getSanitizeROI(lRoi, lFrame);
2895
2896 hwc_rect rFrame = fullFrame;
2897 rFrame.left = lFrame.right;
2898 hwc_rect rRoi = getIntersection(roi, rFrame);
2899
2900 // Align ROI coordinates to panel restrictions
2901 rRoi = getSanitizeROI(rRoi, rFrame);
2902
2903 roi = getUnion(lRoi, rRoi);
2904
2905 ctx->listStats[mDpy].lRoi = roi;
2906 if(!validateAndApplyROI(ctx, list))
2907 resetROI(ctx, mDpy);
2908
2909 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2910 __FUNCTION__,
2911 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2912 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2913 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2914 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2915}
2916
Saurabh Shahab47c692014-02-12 18:45:57 -08002917bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002918 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002919 private_handle_t *hnd = (private_handle_t *)layer->handle;
2920 hwc_rect_t dst = layer->displayFrame;
2921 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2922 pipe_info.lIndex = ovutils::OV_INVALID;
2923 pipe_info.rIndex = ovutils::OV_INVALID;
2924
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002925 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2926 trimAgainstROI(ctx,crop, dst);
2927
Saurabh Shahab47c692014-02-12 18:45:57 -08002928 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2929 //should have a higher priority than the right one. Pipe priorities are
2930 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002931
Saurabh Shahc62f3982014-03-05 14:28:26 -08002932 Overlay::PipeSpecs pipeSpecs;
2933 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2934 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2935 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2936 pipeSpecs.dpy = mDpy;
2937 pipeSpecs.fb = false;
2938
Saurabh Shahab47c692014-02-12 18:45:57 -08002939 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002940 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002941 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002942 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002943 }
2944
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002945 /* Use 2 pipes IF
2946 a) Layer's crop width is > 2048 or
2947 b) Layer's dest width > 2048 or
2948 c) On primary, driver has indicated with caps to split always. This is
2949 based on an empirically derived value of panel height. Applied only
2950 if the layer's width is > mixer's width
2951 */
2952
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302953 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002954 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302955 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002956 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2957 const uint32_t dstWidth = dst.right - dst.left;
2958 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002959 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002960 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002961 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002962 crop.bottom - crop.top;
2963 //Approximation to actual clock, ignoring the common factors in pipe and
2964 //mixer cases like line_time
2965 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2966 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002967
Saurabh Shah05f4e222015-02-05 14:36:22 -08002968 const uint32_t downscale = getRotDownscale(ctx, layer);
2969 if(downscale) {
2970 cropWidth /= downscale;
2971 cropHeight /= downscale;
2972 }
2973
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002974 if(dstWidth > mdpHw.getMaxPipeWidth() or
2975 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002976 (primarySplitAlways and
2977 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002978 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002979 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002980 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002981 }
2982
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002983 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2984 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002985 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002986 }
2987 }
2988
2989 return true;
2990}
2991
Saurabh Shahab47c692014-02-12 18:45:57 -08002992int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2993 PipeLayerPair& PipeLayerPair) {
2994 private_handle_t *hnd = (private_handle_t *)layer->handle;
2995 if(!hnd) {
2996 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2997 return -1;
2998 }
2999 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
3000 MdpPipeInfoSplit& mdp_info =
3001 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
3002 Rotator **rot = &PipeLayerPair.rot;
3003 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08003004 eDest lDest = mdp_info.lIndex;
3005 eDest rDest = mdp_info.rIndex;
3006 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
3007 hwc_rect_t dst = layer->displayFrame;
3008 int transform = layer->transform;
3009 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003010 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08003011 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08003012 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003013 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08003014
3015 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
3016 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
3017
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08003018 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
3019 /* MDP driver crops layer coordinates against ROI in Non-Split
3020 * and Split MDP comp. But HWC needs to crop them for source split.
3021 * Reason: 1) Source split is efficient only when the final effective
3022 * load is distributed evenly across mixers.
3023 * 2) We have to know the effective width of the layer that
3024 * the ROI needs to find the no. of pipes the layer needs.
3025 */
3026 trimAgainstROI(ctx, crop, dst);
3027 }
3028
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05003029 if(needs3DComposition(ctx, mDpy) &&
3030 get3DFormat(hnd) != HAL_NO_3D){
3031 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
3032 rDest, &PipeLayerPair.rot);
3033 }
3034
Saurabh Shahab47c692014-02-12 18:45:57 -08003035 // Handle R/B swap
3036 if (layer->flags & HWC_FORMAT_RB_SWAP) {
3037 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
3038 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
3039 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
3040 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
3041 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003042 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07003043 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
3044 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07003045 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07003046 /* Calculate the external display position based on MDP downscale,
3047 ActionSafe, and extorientation features. */
3048 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08003049
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003050 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003051 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08003052
3053 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3054 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07003055 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08003056 }
3057
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003058 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003059 (*rot) = ctx->mRotMgr->getNext();
3060 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07003061 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003062 //If the video is using a single pipe, enable BWC
3063 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08003064 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
3065 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07003066 }
Saurabh Shahab47c692014-02-12 18:45:57 -08003067 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07003068 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08003069 ALOGE("%s: configRotator failed!", __FUNCTION__);
3070 return -1;
3071 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07003072 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07003073 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08003074 }
3075
3076 //If 2 pipes being used, divide layer into half, crop and dst
3077 hwc_rect_t cropL = crop;
3078 hwc_rect_t cropR = crop;
3079 hwc_rect_t dstL = dst;
3080 hwc_rect_t dstR = dst;
3081 if(lDest != OV_INVALID && rDest != OV_INVALID) {
3082 cropL.right = (crop.right + crop.left) / 2;
3083 cropR.left = cropL.right;
3084 sanitizeSourceCrop(cropL, cropR, hnd);
3085
Saurabh Shahb729b192014-08-15 18:04:24 -07003086 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08003087 //Swap crops on H flip since 2 pipes are being used
3088 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
3089 hwc_rect_t tmp = cropL;
3090 cropL = cropR;
3091 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07003092 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08003093 }
3094
Saurabh Shahb729b192014-08-15 18:04:24 -07003095 //cropSwap trick: If the src and dst widths are both odd, let us say
3096 //2507, then splitting both into half would cause left width to be 1253
3097 //and right 1254. If crop is swapped because of H flip, this will cause
3098 //left crop width to be 1254, whereas left dst width remains 1253, thus
3099 //inducing a scaling that is unaccounted for. To overcome that we add 1
3100 //to the dst width if there is a cropSwap. So if the original width was
3101 //2507, the left dst width will be 1254. Even if the original width was
3102 //even for ex: 2508, the left dst width will still remain 1254.
3103 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08003104 dstR.left = dstL.right;
3105 }
3106
3107 //For the mdp, since either we are pre-rotating or MDP does flips
3108 orient = OVERLAY_TRANSFORM_0;
3109 transform = 0;
3110
3111 //configure left pipe
3112 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003113 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003114 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
3115 (ovutils::eBlending) getBlending(layer->blending));
3116
3117 if(configMdp(ctx->mOverlay, pargL, orient,
3118 cropL, dstL, metadata, lDest) < 0) {
3119 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
3120 return -1;
3121 }
3122 }
3123
3124 //configure right pipe
3125 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003126 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003127 static_cast<eRotFlags>(rotFlags),
3128 layer->planeAlpha,
3129 (ovutils::eBlending) getBlending(layer->blending));
3130 if(configMdp(ctx->mOverlay, pargR, orient,
3131 cropR, dstR, metadata, rDest) < 0) {
3132 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3133 return -1;
3134 }
3135 }
3136
3137 return 0;
3138}
3139
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003140bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3141 Locker::Autolock _l(ctx->mDrawLock);
3142 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3143 char path[MAX_SYSFS_FILE_PATH];
3144 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3145 int fd = open(path, O_RDONLY);
3146 if(fd < 0) {
3147 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3148 return -1;
3149 }
3150 char value[4];
3151 ssize_t size_read = read(fd, value, sizeof(value)-1);
3152 if(size_read <= 0) {
3153 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3154 close(fd);
3155 return -1;
3156 }
3157 close(fd);
3158 value[size_read] = '\0';
3159 return atoi(value);
3160}
3161
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003162int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3163 Locker::Autolock _l(ctx->mDrawLock);
3164 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3165 char path[MAX_SYSFS_FILE_PATH];
3166 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3167 int fd = open(path, O_WRONLY);
3168 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003169 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003170 return -1;
3171 }
3172 char value[4];
3173 snprintf(value, sizeof(value), "%d", (int)enable);
3174 ssize_t ret = write(fd, value, strlen(value));
3175 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003176 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003177 close(fd);
3178 return -1;
3179 }
3180 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003181 return 0;
3182}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003183
3184bool MDPComp::loadPerfLib() {
3185 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3186 bool success = false;
3187 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3188 ALOGE("vendor library not set in ro.vendor.extension_library");
3189 return false;
3190 }
3191
3192 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3193 if(sLibPerfHint) {
3194 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3195 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3196 if (!sPerfLockAcquire || !sPerfLockRelease) {
3197 ALOGE("Failed to load symbols for perfLock");
3198 dlclose(sLibPerfHint);
3199 sLibPerfHint = NULL;
3200 return false;
3201 }
3202 success = true;
3203 ALOGI("Successfully Loaded perf hint API's");
3204 } else {
3205 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3206 }
3207 return success;
3208}
3209
3210void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3211 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3212 return;
3213 }
3214 static int count = sPerfHintWindow;
3215 static int perflockFlag = 0;
3216
3217 /* Send hint to mpctl when single layer is updated
3218 * for a successful number of windows. Hint release
3219 * happens immediately upon multiple layer update.
3220 */
3221 if (onlyVideosUpdating(ctx, list)) {
3222 if(count) {
3223 count--;
3224 }
3225 } else {
3226 if (perflockFlag) {
3227 perflockFlag = 0;
3228 sPerfLockRelease(sPerfLockHandle);
3229 }
3230 count = sPerfHintWindow;
3231 }
3232 if (count == 0 && !perflockFlag) {
3233 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3234 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3235 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003236 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003237 perflockFlag = 1;
3238 }
3239 }
3240}
3241
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003242}; //namespace
3243