blob: eba6f3f61f620f53f4925d50c73fb8dc0f7bb328 [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"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080022#include <dlfcn.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070023#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.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 "
82 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080083 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
84 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] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700111 (mCurrentFrame.drop[index] ? "DROP" :
112 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800113 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
114 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
115 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800116}
117
118bool MDPComp::init(hwc_context_t *ctx) {
119
120 if(!ctx) {
121 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
122 return false;
123 }
124
Saurabh Shah59562ff2014-09-30 16:13:12 -0700125 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800126
127 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530128 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
129 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
131 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800132 sEnabled = true;
133 }
134
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700135 sEnableMixedMode = true;
136 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
137 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
138 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
139 sEnableMixedMode = false;
140 }
141
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700142 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
143
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800144 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700145 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700146 int val = atoi(property);
147 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700148 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800149 }
150
Saurabh Shahacec8e42014-11-25 11:07:04 -0800151 /* Maximum layers allowed to use MDP on secondary panels. If property
152 * doesn't exist, default to 1. Using the property it can be set to 0 or
153 * more.
154 */
155 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
156 int val = atoi(property);
157 sMaxSecLayers = (val >= 0) ? val : 1;
158 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
159 }
160
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400161 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700162 sIdleInvalidator = IdleInvalidator::getInstance();
163 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
164 delete sIdleInvalidator;
165 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400166 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800167 }
radhakrishnac9a67412013-09-25 17:40:42 +0530168
Saurabh Shah7c727642014-06-02 15:47:14 -0700169 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700170 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700171 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
172 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
173 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530174 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530175 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700176
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530177 bool defaultPTOR = false;
178 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
179 //8x16 and 8x39 targets by default
180 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
181 (qdutils::MDPVersion::getInstance().is8x16() ||
182 qdutils::MDPVersion::getInstance().is8x39())) {
183 defaultPTOR = true;
184 }
185
186 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
187 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700188 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
189 HWC_DISPLAY_PRIMARY);
190 }
191
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530192 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
193 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
194 enablePartialUpdateForMDP3 = true;
195 }
196
197 if(!enablePartialUpdateForMDP3 &&
198 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
199 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
200 enablePartialUpdateForMDP3 = true;
201 }
202
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800203 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
204
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800205 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
206 int val = atoi(property);
207 if(val > 0 && loadPerfLib()) {
208 sPerfHintWindow = val;
209 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
210 }
211 }
212
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700213 return true;
214}
215
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800216void MDPComp::reset(hwc_context_t *ctx) {
217 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700218 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800219 ctx->mOverlay->clear(mDpy);
220 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700221}
222
Raj Kamal4393eaa2014-06-06 13:45:20 +0530223void MDPComp::reset() {
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530224 mPrevModeOn = mModeOn;
Raj Kamal4393eaa2014-06-06 13:45:20 +0530225 mModeOn = false;
226}
227
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228void MDPComp::timeout_handler(void *udata) {
229 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530230 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700231
232 if(!ctx) {
233 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
234 return;
235 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530236
237 ctx->mDrawLock.lock();
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530238
239 /* Handle timeout event only if the previous composition
240 on any display is MDP or MIXED*/
241 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
242 if(ctx->mMDPComp[i])
243 handleTimeout =
244 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
245 }
246
247 if(!handleTimeout) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800248 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530249 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800250 return;
251 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700252 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700253 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530254 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700255 return;
256 }
257 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530258 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700259 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700260 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700261}
262
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700263void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
264 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800265 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700266 if(value > maxSupported) {
267 ALOGW("%s: Input exceeds max value supported. Setting to"
268 "max value: %d", __FUNCTION__, maxSupported);
269 }
270 sMaxPipesPerMixer = min(value, maxSupported);
271}
272
Saurabh Shah59562ff2014-09-30 16:13:12 -0700273void MDPComp::setIdleTimeout(const uint32_t& timeout) {
274 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
275
276 if(sIdleInvalidator) {
277 if(timeout <= ONE_REFRESH_PERIOD_MS) {
278 //If the specified timeout is < 1 draw cycle worth, "virtually"
279 //disable idle timeout. The ideal way for clients to disable
280 //timeout is to set it to 0
281 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
282 ALOGI("Disabled idle timeout");
283 return;
284 }
285 sIdleInvalidator->setIdleTimeout(timeout);
286 ALOGI("Idle timeout set to %u", timeout);
287 } else {
288 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
289 }
290}
291
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800292void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800293 hwc_display_contents_1_t* list) {
294 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800295
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800297 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800298 if(!mCurrentFrame.isFBComposed[index]) {
299 layerProp[index].mFlags |= HWC_MDPCOMP;
300 layer->compositionType = HWC_OVERLAY;
301 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800302 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700303 /* Drop the layer when its already present in FB OR when it lies
304 * outside frame's ROI */
305 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800306 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700307 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800308 }
309 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700310}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500311
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800312void MDPComp::setRedraw(hwc_context_t *ctx,
313 hwc_display_contents_1_t* list) {
314 mCurrentFrame.needsRedraw = false;
315 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
316 (list->flags & HWC_GEOMETRY_CHANGED) ||
317 isSkipPresent(ctx, mDpy)) {
318 mCurrentFrame.needsRedraw = true;
319 }
320}
321
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800322MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700323 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700324 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800325}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800326
Saurabh Shahaa236822013-04-24 18:07:26 -0700327void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700328 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800329 if(mdpToLayer[i].pipeInfo) {
330 delete mdpToLayer[i].pipeInfo;
331 mdpToLayer[i].pipeInfo = NULL;
332 //We dont own the rotator
333 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800334 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800335 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336
337 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
338 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700339 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800340
Saurabh Shahaa236822013-04-24 18:07:26 -0700341 layerCount = numLayers;
342 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800343 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700344 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800345 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800346}
347
Saurabh Shahaa236822013-04-24 18:07:26 -0700348void MDPComp::FrameInfo::map() {
349 // populate layer and MDP maps
350 int mdpIdx = 0;
351 for(int idx = 0; idx < layerCount; idx++) {
352 if(!isFBComposed[idx]) {
353 mdpToLayer[mdpIdx].listIndex = idx;
354 layerToMDP[idx] = mdpIdx++;
355 }
356 }
357}
358
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800359MDPComp::LayerCache::LayerCache() {
360 reset();
361}
362
363void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700364 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530365 memset(&isFBComposed, true, sizeof(isFBComposed));
366 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800367 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700368}
369
370void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530371 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700372 for(int i = 0; i < numAppLayers; i++) {
373 hnd[i] = list->hwLayers[i].handle;
374 }
375}
376
377void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700378 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530379 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
380 memcpy(&drop, &curFrame.drop, sizeof(drop));
381}
382
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800383bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
384 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530385 if(layerCount != curFrame.layerCount)
386 return false;
387 for(int i = 0; i < curFrame.layerCount; i++) {
388 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
389 (curFrame.drop[i] != drop[i])) {
390 return false;
391 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800392 if(curFrame.isFBComposed[i] &&
393 (hnd[i] != list->hwLayers[i].handle)){
394 return false;
395 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530396 }
397 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800398}
399
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530400bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
401 hwc_display_contents_1_t* list) {
402
403 if(layerCount != ctx->listStats[dpy].numAppLayers)
404 return false;
405
406 if((list->flags & HWC_GEOMETRY_CHANGED) ||
407 isSkipPresent(ctx, dpy)) {
408 return false;
409 }
410
411 for(int i = 0; i < layerCount; i++) {
412 if(hnd[i] != list->hwLayers[i].handle)
413 return false;
414 }
415
416 return true;
417}
418
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700419bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
420 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800421 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530422 (not isValidDimension(ctx,layer)) ||
423 isSkipLayer(layer)) {
424 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700425 return false;
426 }
427 return true;
428}
429
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530430bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800431 private_handle_t *hnd = (private_handle_t *)layer->handle;
432
433 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700434 if (layer->flags & HWC_COLOR_FILL) {
435 // Color layer
436 return true;
437 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700438 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800439 return false;
440 }
441
Naseer Ahmede850a802013-09-06 13:12:52 -0400442 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400443 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400444 return false;
445
Saurabh Shah62e1d732013-09-17 10:44:05 -0700446 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700447 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700448 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700449 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
450 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700451 int dst_w = dst.right - dst.left;
452 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800453 float w_scale = ((float)crop_w / (float)dst_w);
454 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530455 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700456
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800457 /* Workaround for MDP HW limitation in DSI command mode panels where
458 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
459 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530460 * There also is a HW limilation in MDP, minimum block size is 2x2
461 * Fallback to GPU if height is less than 2.
462 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700463 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800464 return false;
465
Ramkumar Radhakrishnan1a763e92015-03-19 16:46:46 -0700466 /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
467 * those cases
468 */
469 if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
470 return false;
471 }
472
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800473 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530474 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800475 const float w_dscale = w_scale;
476 const float h_dscale = h_scale;
477
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800478 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700479
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530480 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700481 /* On targets that doesnt support Decimation (eg.,8x26)
482 * maximum downscale support is overlay pipe downscale.
483 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800484 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530485 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700486 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800487 return false;
488 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700489 // Decimation on macrotile format layers is not supported.
490 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530491 /* Bail out if
492 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700493 * 2. exceeds maximum downscale limit
494 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800495 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530496 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700497 w_dscale > maxMDPDownscale ||
498 h_dscale > maxMDPDownscale) {
499 return false;
500 }
501 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800502 return false;
503 }
504 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700505 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700506 return false;
507 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700508 }
509
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800510 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530511 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800512 const float w_uscale = 1.0f / w_scale;
513 const float h_uscale = 1.0f / h_scale;
514
515 if(w_uscale > upscale || h_uscale > upscale)
516 return false;
517 }
518
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800519 return true;
520}
521
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800522bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700523 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800524
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800525 if(!isEnabled()) {
526 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700527 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530528 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530529 qdutils::MDPVersion::getInstance().is8x16() ||
530 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800531 ctx->mVideoTransFlag &&
532 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700533 //1 Padding round to shift pipes across mixers
534 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
535 __FUNCTION__);
536 ret = false;
Raj Kamalc0d34242015-03-17 20:53:14 +0530537 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
538 qdutils::MDPVersion::getInstance().is8x16() ||
539 qdutils::MDPVersion::getInstance().is8x39()) &&
540 !mDpy && isSecondaryAnimating(ctx) &&
541 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
542 ALOGD_IF(isDebug(),"%s: Display animation in progress",
543 __FUNCTION__);
544 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700545 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
546 /* TODO: freeing up all the resources only for the targets having total
547 number of pipes < 8. Need to analyze number of VIG pipes used
548 for primary in previous draw cycle and accordingly decide
549 whether to fall back to full GPU comp or video only comp
550 */
551 if(isSecondaryConfiguring(ctx)) {
552 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
553 __FUNCTION__);
554 ret = false;
555 } else if(ctx->isPaddingRound) {
556 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
557 __FUNCTION__,mDpy);
558 ret = false;
559 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800560 } else if (ctx->isDMAStateChanging) {
561 // Bail out if a padding round has been invoked in order to switch DMA
562 // state to block mode. We need this to cater for the case when a layer
563 // requires rotation in the current frame.
564 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
565 __FUNCTION__);
566 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700567 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800568
Saurabh Shahaa236822013-04-24 18:07:26 -0700569 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800570}
571
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800572void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
573 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800574 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800575 dst = getIntersection(dst, roi);
576 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577}
578
579/* 1) Identify layers that are not visible or lying outside the updating ROI and
580 * drop them from composition.
581 * 2) If we have a scaling layer which needs cropping against generated
582 * ROI, reset ROI to full resolution. */
583bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
584 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700585 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800586 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800587
588 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800589 if(!isValidRect(visibleRect)) {
590 mCurrentFrame.drop[i] = true;
591 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800592 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800593 }
594
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700595 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700596 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800597 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700598
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700599 if(!isValidRect(res)) {
600 mCurrentFrame.drop[i] = true;
601 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800602 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700603 /* Reset frame ROI when any layer which needs scaling also needs ROI
604 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800605 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800606 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700607 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
608 mCurrentFrame.dropCount = 0;
609 return false;
610 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800611
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800612 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530613 if (layer->blending == HWC_BLENDING_NONE &&
614 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800615 visibleRect = deductRect(visibleRect, res);
616 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700617 }
618 return true;
619}
620
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800621/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
622 * are updating. If DirtyRegion is applicable, calculate it by accounting all
623 * the changing layer's dirtyRegion. */
624void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
625 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700626 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800627 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700628 return;
629
630 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800631 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
632 (int)ctx->dpyAttr[mDpy].yres};
633
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700634 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800635 hwc_layer_1_t* layer = &list->hwLayers[index];
636 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800637 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700638 hwc_rect_t dst = layer->displayFrame;
639 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800640
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800641#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530642 if(!needsScaling(layer) && !layer->transform &&
643 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700644 {
645 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
646 int x_off = dst.left - src.left;
647 int y_off = dst.top - src.top;
648 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
649 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800650#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800651
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800652 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700653 }
654 }
655
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800656 /* No layer is updating. Still SF wants a refresh.*/
657 if(!isValidRect(roi))
658 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800659
660 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800661 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800662
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800663 ctx->listStats[mDpy].lRoi = roi;
664 if(!validateAndApplyROI(ctx, list))
665 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700666
667 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800668 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
669 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
670}
671
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800672void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
673 hwc_rect &dst) {
674 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
675 ctx->listStats[mDpy].rRoi);
676 hwc_rect tmpDst = getIntersection(dst, roi);
677 if(!isSameRect(dst, tmpDst)) {
678 crop.left = crop.left + (tmpDst.left - dst.left);
679 crop.top = crop.top + (tmpDst.top - dst.top);
680 crop.right = crop.left + (tmpDst.right - tmpDst.left);
681 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
682 dst = tmpDst;
683 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800684}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800685
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800686/* 1) Identify layers that are not visible or lying outside BOTH the updating
687 * ROI's and drop them from composition. If a layer is spanning across both
688 * the halves of the screen but needed by only ROI, the non-contributing
689 * half will not be programmed for MDP.
690 * 2) If we have a scaling layer which needs cropping against generated
691 * ROI, reset ROI to full resolution. */
692bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
693 hwc_display_contents_1_t* list) {
694
695 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
696
697 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
698 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
699
700 for(int i = numAppLayers - 1; i >= 0; i--){
701 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
702 {
703 mCurrentFrame.drop[i] = true;
704 mCurrentFrame.dropCount++;
705 continue;
706 }
707
708 const hwc_layer_1_t* layer = &list->hwLayers[i];
709 hwc_rect_t dstRect = layer->displayFrame;
710
711 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
712 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
713 hwc_rect_t res = getUnion(l_res, r_res);
714
715 if(!isValidRect(l_res) && !isValidRect(r_res)) {
716 mCurrentFrame.drop[i] = true;
717 mCurrentFrame.dropCount++;
718 } else {
719 /* Reset frame ROI when any layer which needs scaling also needs ROI
720 * cropping */
721 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
722 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
723 mCurrentFrame.dropCount = 0;
724 return false;
725 }
726
radhakrishna4efbdd62014-11-03 13:19:27 +0530727 if (layer->blending == HWC_BLENDING_NONE &&
728 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800729 visibleRectL = deductRect(visibleRectL, l_res);
730 visibleRectR = deductRect(visibleRectR, r_res);
731 }
732 }
733 }
734 return true;
735}
736/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
737 * are updating. If DirtyRegion is applicable, calculate it by accounting all
738 * the changing layer's dirtyRegion. */
739void MDPCompSplit::generateROI(hwc_context_t *ctx,
740 hwc_display_contents_1_t* list) {
741 if(!canPartialUpdate(ctx, list))
742 return;
743
744 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
745 int lSplit = getLeftSplit(ctx, mDpy);
746
747 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
748 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
749
750 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
751 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
752
753 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
754 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
755
756 for(int index = 0; index < numAppLayers; index++ ) {
757 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800758 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800759 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800760 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700761 hwc_rect_t dst = layer->displayFrame;
762 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800763
764#ifdef QCOM_BSP
765 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700766 {
767 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
768 int x_off = dst.left - src.left;
769 int y_off = dst.top - src.top;
770 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
771 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800772#endif
773
774 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
775 if(isValidRect(l_dst))
776 l_roi = getUnion(l_roi, l_dst);
777
778 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
779 if(isValidRect(r_dst))
780 r_roi = getUnion(r_roi, r_dst);
781 }
782 }
783
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700784 /* For panels that cannot accept commands in both the interfaces, we cannot
785 * send two ROI's (for each half). We merge them into single ROI and split
786 * them across lSplit for MDP mixer use. The ROI's will be merged again
787 * finally before udpating the panel in the driver. */
788 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
789 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
790 l_roi = getIntersection(temp_roi, l_frame);
791 r_roi = getIntersection(temp_roi, r_frame);
792 }
793
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800794 /* No layer is updating. Still SF wants a refresh. */
795 if(!isValidRect(l_roi) && !isValidRect(r_roi))
796 return;
797
798 l_roi = getSanitizeROI(l_roi, l_frame);
799 r_roi = getSanitizeROI(r_roi, r_frame);
800
801 ctx->listStats[mDpy].lRoi = l_roi;
802 ctx->listStats[mDpy].rRoi = r_roi;
803
804 if(!validateAndApplyROI(ctx, list))
805 resetROI(ctx, mDpy);
806
807 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
808 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
809 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
810 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
811 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
812 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700813}
814
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800815/* Checks for conditions where all the layers marked for MDP comp cannot be
816 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800817bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800818 hwc_display_contents_1_t* list){
819
Saurabh Shahaa236822013-04-24 18:07:26 -0700820 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800821
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700822 // Fall back to video only composition, if AIV video mode is enabled
823 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700824 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
825 __FUNCTION__, mDpy);
826 return false;
827 }
828
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530829 /* No Idle fall back if secure display or secure RGB layers are present
830 * or if there is only a single layer being composed */
831 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
832 !ctx->listStats[mDpy].secureRGBCount &&
833 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700834 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
835 return false;
836 }
837
Raj Kamalc0d34242015-03-17 20:53:14 +0530838 if(!mDpy && isSecondaryAnimating(ctx) &&
839 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
840 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
841 ALOGD_IF(isDebug(),"%s: Display animation in progress",
842 __FUNCTION__);
843 return false;
844 }
845
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700846 // if secondary is configuring or Padding round, fall back to video only
847 // composition and release all assigned non VIG pipes from primary.
848 if(isSecondaryConfiguring(ctx)) {
849 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
850 __FUNCTION__);
851 return false;
852 } else if(ctx->isPaddingRound) {
853 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
854 __FUNCTION__,mDpy);
855 return false;
856 }
857
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500858 // No MDP composition for 3D
859 if(needs3DComposition(ctx, mDpy))
860 return false;
861
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700862 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800863 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700864 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800865 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
866 return false;
867 }
868
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800869 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800870 hwc_layer_1_t* layer = &list->hwLayers[i];
871 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800872
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800873 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700874 if(!canUseRotator(ctx, mDpy)) {
875 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
876 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700877 return false;
878 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800879 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530880
881 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
882 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800883 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700884 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530885 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
886 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
887 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800888 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700889
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700890 if(ctx->mAD->isDoable()) {
891 return false;
892 }
893
Saurabh Shahaa236822013-04-24 18:07:26 -0700894 //If all above hard conditions are met we can do full or partial MDP comp.
895 bool ret = false;
896 if(fullMDPComp(ctx, list)) {
897 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700898 } else if(fullMDPCompWithPTOR(ctx, list)) {
899 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700900 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700901 ret = true;
902 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530903
Saurabh Shahaa236822013-04-24 18:07:26 -0700904 return ret;
905}
906
907bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700908
909 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
910 return false;
911
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700912 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
913 for(int i = 0; i < numAppLayers; i++) {
914 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700915 if(not mCurrentFrame.drop[i] and
916 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700917 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
918 return false;
919 }
920 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800921
Saurabh Shahaa236822013-04-24 18:07:26 -0700922 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700923 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
924 sizeof(mCurrentFrame.isFBComposed));
925 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
926 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700927
Raj Kamal389d6e32014-08-04 14:43:24 +0530928 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800929 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530930 }
931
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800932 if(!postHeuristicsHandling(ctx, list)) {
933 ALOGD_IF(isDebug(), "post heuristic handling failed");
934 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700935 return false;
936 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700937 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
938 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700939 return true;
940}
941
Sushil Chauhandefd3522014-05-13 18:17:12 -0700942/* Full MDP Composition with Peripheral Tiny Overlap Removal.
943 * MDP bandwidth limitations can be avoided, if the overlap region
944 * covered by the smallest layer at a higher z-order, gets composed
945 * by Copybit on a render buffer, which can be queued to MDP.
946 */
947bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
948 hwc_display_contents_1_t* list) {
949
950 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
951 const int stagesForMDP = min(sMaxPipesPerMixer,
952 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
953
954 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700955 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700956 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
957 return false;
958 }
959
960 // Frame level checks
961 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
962 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
963 isSecurePresent(ctx, mDpy)) {
964 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
965 return false;
966 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700967 // MDP comp checks
968 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700969 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700970 if(not isSupportedForMDPComp(ctx, layer)) {
971 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
972 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700973 }
974 }
975
Sushil Chauhandefd3522014-05-13 18:17:12 -0700976 /* We cannot use this composition mode, if:
977 1. A below layer needs scaling.
978 2. Overlap is not peripheral to display.
979 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700980 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700981 */
982
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
984 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
985 memset(overlapRect, 0, sizeof(overlapRect));
986 int layerPixelCount, minPixelCount = 0;
987 int numPTORLayersFound = 0;
988 for (int i = numAppLayers-1; (i >= 0 &&
989 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700990 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700991 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700992 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700993 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
994 // PTOR layer should be peripheral and cannot have transform
995 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
996 has90Transform(layer)) {
997 continue;
998 }
999 if((3 * (layerPixelCount + minPixelCount)) >
1000 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
1001 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
1002 continue;
1003 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001004 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001005 for (int j = i-1; j >= 0; j--) {
1006 // Check if the layers below this layer qualifies for PTOR comp
1007 hwc_layer_1_t* layer = &list->hwLayers[j];
1008 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001009 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001010 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001011 if (isValidRect(getIntersection(dispFrame, disFrame))) {
1012 if (has90Transform(layer) || needsScaling(layer)) {
1013 found = false;
1014 break;
1015 }
1016 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001017 }
1018 }
1019 // Store the minLayer Index
1020 if(found) {
1021 minLayerIndex[numPTORLayersFound] = i;
1022 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1023 minPixelCount += layerPixelCount;
1024 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001025 }
1026 }
1027
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001028 // No overlap layers
1029 if (!numPTORLayersFound)
1030 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001031
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001032 // Store the displayFrame and the sourceCrops of the layers
1033 hwc_rect_t displayFrame[numAppLayers];
1034 hwc_rect_t sourceCrop[numAppLayers];
1035 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001036 hwc_layer_1_t* layer = &list->hwLayers[i];
1037 displayFrame[i] = layer->displayFrame;
1038 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001039 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001040
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301041 /**
1042 * It's possible that 2 PTOR layers might have overlapping.
1043 * In such case, remove the intersection(again if peripheral)
1044 * from the lower PTOR layer to avoid overlapping.
1045 * If intersection is not on peripheral then compromise
1046 * by reducing number of PTOR layers.
1047 **/
1048 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1049 if(isValidRect(commonRect)) {
1050 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1051 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1052 }
1053
1054 ctx->mPtorInfo.count = numPTORLayersFound;
1055 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1056 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1057 }
1058
1059 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1060 // reset PTOR
1061 ctx->mPtorInfo.count = 0;
1062 if(isValidRect(commonRect)) {
1063 // If PTORs are intersecting restore displayframe of PTOR[1]
1064 // before returning, as we have modified it above.
1065 list->hwLayers[minLayerIndex[1]].displayFrame =
1066 displayFrame[minLayerIndex[1]];
1067 }
1068 return false;
1069 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001070 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1071 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1072
Xu Yangcda012c2014-07-30 21:57:21 +08001073 // Store the blending mode, planeAlpha, and transform of PTOR layers
1074 int32_t blending[numPTORLayersFound];
1075 uint8_t planeAlpha[numPTORLayersFound];
1076 uint32_t transform[numPTORLayersFound];
1077
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001078 for(int j = 0; j < numPTORLayersFound; j++) {
1079 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001080
1081 // Update src crop of PTOR layer
1082 hwc_layer_1_t* layer = &list->hwLayers[index];
1083 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1084 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1085 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1086 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1087
1088 // Store & update w, h, format of PTOR layer
1089 private_handle_t *hnd = (private_handle_t *)layer->handle;
1090 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1091 layerWhf[j] = whf;
1092 hnd->width = renderBuf->width;
1093 hnd->height = renderBuf->height;
1094 hnd->format = renderBuf->format;
1095
Xu Yangcda012c2014-07-30 21:57:21 +08001096 // Store & update blending mode, planeAlpha and transform of PTOR layer
1097 blending[j] = layer->blending;
1098 planeAlpha[j] = layer->planeAlpha;
1099 transform[j] = layer->transform;
1100 layer->blending = HWC_BLENDING_NONE;
1101 layer->planeAlpha = 0xFF;
1102 layer->transform = 0;
1103
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001104 // Remove overlap from crop & displayFrame of below layers
1105 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001106 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001107 if(!isValidRect(getIntersection(layer->displayFrame,
1108 overlapRect[j]))) {
1109 continue;
1110 }
1111 // Update layer attributes
1112 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1113 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301114 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001115 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1116 layer->transform);
1117 layer->sourceCropf.left = (float)srcCrop.left;
1118 layer->sourceCropf.top = (float)srcCrop.top;
1119 layer->sourceCropf.right = (float)srcCrop.right;
1120 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1121 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001122 }
1123
1124 mCurrentFrame.mdpCount = numAppLayers;
1125 mCurrentFrame.fbCount = 0;
1126 mCurrentFrame.fbZ = -1;
1127
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301128 for (int j = 0; j < numAppLayers; j++) {
1129 if(isValidRect(list->hwLayers[j].displayFrame)) {
1130 mCurrentFrame.isFBComposed[j] = false;
1131 } else {
1132 mCurrentFrame.mdpCount--;
1133 mCurrentFrame.drop[j] = true;
1134 }
1135 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001136
1137 bool result = postHeuristicsHandling(ctx, list);
1138
1139 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001140 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001141 hwc_layer_1_t* layer = &list->hwLayers[i];
1142 layer->displayFrame = displayFrame[i];
1143 layer->sourceCropf.left = (float)sourceCrop[i].left;
1144 layer->sourceCropf.top = (float)sourceCrop[i].top;
1145 layer->sourceCropf.right = (float)sourceCrop[i].right;
1146 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1147 }
1148
Xu Yangcda012c2014-07-30 21:57:21 +08001149 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001150 for (int i = 0; i < numPTORLayersFound; i++) {
1151 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001152 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001153 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1154 hnd->width = layerWhf[i].w;
1155 hnd->height = layerWhf[i].h;
1156 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001157 layer->blending = blending[i];
1158 layer->planeAlpha = planeAlpha[i];
1159 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001160 }
1161
Sushil Chauhandefd3522014-05-13 18:17:12 -07001162 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001163 // reset PTOR
1164 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001165 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001166 } else {
1167 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1168 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001169 }
1170
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001171 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1172 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001173 return result;
1174}
1175
Saurabh Shahaa236822013-04-24 18:07:26 -07001176bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1177{
radhakrishnac3198ff2015-03-10 17:10:02 +05301178 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1179 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001180 return false;
1181 }
1182
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001183 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301184 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1185 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001186 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001187 cacheBasedComp(ctx, list);
1188 } else {
1189 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001190 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001191 }
1192
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001193 return ret;
1194}
1195
1196bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1197 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001198 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1199 return false;
1200
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001201 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001202 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001203 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001204
1205 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1206 for(int i = 0; i < numAppLayers; i++) {
1207 if(!mCurrentFrame.isFBComposed[i]) {
1208 hwc_layer_1_t* layer = &list->hwLayers[i];
1209 if(not isSupportedForMDPComp(ctx, layer)) {
1210 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1211 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001212 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001213 return false;
1214 }
1215 }
1216 }
1217
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001218 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001219 /* mark secure RGB layers for MDP comp */
1220 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301221 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001222 if(!ret) {
1223 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001224 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001225 return false;
1226 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001227
1228 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001229
Raj Kamal389d6e32014-08-04 14:43:24 +05301230 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001231 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301232 }
1233
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001234 if(!postHeuristicsHandling(ctx, list)) {
1235 ALOGD_IF(isDebug(), "post heuristic handling failed");
1236 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001237 return false;
1238 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001239 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1240 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001241
Saurabh Shahaa236822013-04-24 18:07:26 -07001242 return true;
1243}
1244
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001245bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001246 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001247 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1248 return false;
1249
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001250 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001251 return false;
1252 }
1253
Saurabh Shahb772ae32013-11-18 15:40:02 -08001254 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001255 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1256 const int stagesForMDP = min(sMaxPipesPerMixer,
1257 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001258
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001259 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1260 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1261 int lastMDPSupportedIndex = numAppLayers;
1262 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001263
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001264 //Find the minimum MDP batch size
1265 for(int i = 0; i < numAppLayers;i++) {
1266 if(mCurrentFrame.drop[i]) {
1267 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001268 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001269 }
1270 hwc_layer_1_t* layer = &list->hwLayers[i];
1271 if(not isSupportedForMDPComp(ctx, layer)) {
1272 lastMDPSupportedIndex = i;
1273 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1274 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001275 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001276 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001277 }
1278
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001279 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1280 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1281 mCurrentFrame.dropCount);
1282
1283 //Start at a point where the fb batch should at least have 2 layers, for
1284 //this mode to be justified.
1285 while(fbBatchSize < 2) {
1286 ++fbBatchSize;
1287 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001288 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001289
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001290 //If there are no layers for MDP, this mode doesnt make sense.
1291 if(mdpBatchSize < 1) {
1292 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1293 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001294 return false;
1295 }
1296
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001297 mCurrentFrame.reset(numAppLayers);
1298
1299 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1300 while(mdpBatchSize > 0) {
1301 //Mark layers for MDP comp
1302 int mdpBatchLeft = mdpBatchSize;
1303 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1304 if(mCurrentFrame.drop[i]) {
1305 continue;
1306 }
1307 mCurrentFrame.isFBComposed[i] = false;
1308 --mdpBatchLeft;
1309 }
1310
1311 mCurrentFrame.fbZ = mdpBatchSize;
1312 mCurrentFrame.fbCount = fbBatchSize;
1313 mCurrentFrame.mdpCount = mdpBatchSize;
1314
1315 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1316 __FUNCTION__, mdpBatchSize, fbBatchSize,
1317 mCurrentFrame.dropCount);
1318
1319 if(postHeuristicsHandling(ctx, list)) {
1320 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001321 __FUNCTION__);
1322 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1323 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001324 return true;
1325 }
1326
1327 reset(ctx);
1328 --mdpBatchSize;
1329 ++fbBatchSize;
1330 }
1331
1332 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001333}
1334
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001335bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301336 if(mDpy or isSecurePresent(ctx, mDpy) or
1337 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001338 return false;
1339 }
1340 return true;
1341}
1342
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001343bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1344 hwc_display_contents_1_t* list){
1345 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1346 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001347 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001348 return false;
1349 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001350 if(ctx->listStats[mDpy].secureUI)
1351 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001352 return true;
1353}
1354
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001355bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1356 hwc_display_contents_1_t* list) {
1357 const bool secureOnly = true;
1358 return videoOnlyComp(ctx, list, not secureOnly) or
1359 videoOnlyComp(ctx, list, secureOnly);
1360}
1361
1362bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001363 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001364 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1365 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301366
Saurabh Shahaa236822013-04-24 18:07:26 -07001367 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301368 if(!isSecurePresent(ctx, mDpy)) {
1369 /* Bail out if we are processing only secured video layers
1370 * and we dont have any */
1371 if(secureOnly) {
1372 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1373 return false;
1374 }
1375 /* No Idle fall back for secure video layers and if there is only
1376 * single layer being composed. */
1377 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1378 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1379 return false;
1380 }
1381 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001382
Saurabh Shahaa236822013-04-24 18:07:26 -07001383 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001384 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001385 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001386 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001387
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001388 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1389 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001390 return false;
1391 }
1392
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001393 if(mCurrentFrame.fbCount)
1394 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001395
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001396 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001397 adjustForSourceSplit(ctx, list);
1398 }
1399
1400 if(!postHeuristicsHandling(ctx, list)) {
1401 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301402 if(errno == ENOBUFS) {
1403 ALOGD_IF(isDebug(), "SMP Allocation failed");
1404 //On SMP allocation failure in video only comp add padding round
1405 ctx->isPaddingRound = true;
1406 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001407 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001408 return false;
1409 }
1410
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001411 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1412 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001413 return true;
1414}
1415
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001416/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1417bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1418 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001419 // Fall back to video only composition, if AIV video mode is enabled
1420 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001421 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1422 __FUNCTION__, mDpy);
1423 return false;
1424 }
1425
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001426 // No MDP composition for 3D
1427 if(needs3DComposition(ctx,mDpy))
1428 return false;
1429
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001430 const bool secureOnly = true;
1431 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1432 mdpOnlyLayersComp(ctx, list, secureOnly);
1433
1434}
1435
1436bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1437 hwc_display_contents_1_t* list, bool secureOnly) {
1438
1439 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1440 return false;
1441
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301442 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1443 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1444 /* Bail out if we are processing only secured video/ui layers
1445 * and we dont have any */
1446 if(secureOnly) {
1447 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1448 return false;
1449 }
1450 /* No Idle fall back for secure video/ui layers and if there is only
1451 * single layer being composed. */
1452 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1453 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1454 return false;
1455 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001456 }
1457
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001458 /* Bail out if we dont have any secure RGB layers */
1459 if (!ctx->listStats[mDpy].secureRGBCount) {
1460 reset(ctx);
1461 return false;
1462 }
1463
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001464 mCurrentFrame.reset(numAppLayers);
1465 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1466
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001467 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001468 /* mark secure RGB layers for MDP comp */
1469 updateSecureRGB(ctx, list);
1470
1471 if(mCurrentFrame.mdpCount == 0) {
1472 reset(ctx);
1473 return false;
1474 }
1475
1476 /* find the maximum batch of layers to be marked for framebuffer */
1477 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1478 if(!ret) {
1479 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1480 reset(ctx);
1481 return false;
1482 }
1483
1484 if(sEnableYUVsplit){
1485 adjustForSourceSplit(ctx, list);
1486 }
1487
1488 if(!postHeuristicsHandling(ctx, list)) {
1489 ALOGD_IF(isDebug(), "post heuristic handling failed");
1490 reset(ctx);
1491 return false;
1492 }
1493
1494 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1495 __FUNCTION__);
1496 return true;
1497}
1498
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001499/* Checks for conditions where YUV layers cannot be bypassed */
1500bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001501 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001502 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001503 return false;
1504 }
1505
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001506 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001507 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1508 return false;
1509 }
1510
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001511 if(isSecuring(ctx, layer)) {
1512 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1513 return false;
1514 }
1515
Saurabh Shah4fdde762013-04-30 18:47:33 -07001516 if(!isValidDimension(ctx, layer)) {
1517 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1518 __FUNCTION__);
1519 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001520 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001521
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001522 if(layer->planeAlpha < 0xFF) {
1523 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1524 in video only mode",
1525 __FUNCTION__);
1526 return false;
1527 }
1528
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001529 return true;
1530}
1531
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001532/* Checks for conditions where Secure RGB layers cannot be bypassed */
1533bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1534 if(isSkipLayer(layer)) {
1535 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1536 __FUNCTION__, mDpy);
1537 return false;
1538 }
1539
1540 if(isSecuring(ctx, layer)) {
1541 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1542 return false;
1543 }
1544
1545 if(not isSupportedForMDPComp(ctx, layer)) {
1546 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1547 __FUNCTION__);
1548 return false;
1549 }
1550 return true;
1551}
1552
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301553/* starts at fromIndex and check for each layer to find
1554 * if it it has overlapping with any Updating layer above it in zorder
1555 * till the end of the batch. returns true if it finds any intersection */
1556bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1557 int fromIndex, int toIndex) {
1558 for(int i = fromIndex; i < toIndex; i++) {
1559 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1560 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1561 return false;
1562 }
1563 }
1564 }
1565 return true;
1566}
1567
1568/* Checks if given layer at targetLayerIndex has any
1569 * intersection with all the updating layers in beween
1570 * fromIndex and toIndex. Returns true if it finds intersectiion */
1571bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1572 int fromIndex, int toIndex, int targetLayerIndex) {
1573 for(int i = fromIndex; i <= toIndex; i++) {
1574 if(!mCurrentFrame.isFBComposed[i]) {
1575 if(areLayersIntersecting(&list->hwLayers[i],
1576 &list->hwLayers[targetLayerIndex])) {
1577 return true;
1578 }
1579 }
1580 }
1581 return false;
1582}
1583
1584int MDPComp::getBatch(hwc_display_contents_1_t* list,
1585 int& maxBatchStart, int& maxBatchEnd,
1586 int& maxBatchCount) {
1587 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301588 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001589 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301590 while (i < mCurrentFrame.layerCount) {
1591 int batchCount = 0;
1592 int batchStart = i;
1593 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001594 /* Adjust batch Z order with the dropped layers so far */
1595 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301596 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301597 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301598 while(i < mCurrentFrame.layerCount) {
1599 if(!mCurrentFrame.isFBComposed[i]) {
1600 if(!batchCount) {
1601 i++;
1602 break;
1603 }
1604 updatingLayersAbove++;
1605 i++;
1606 continue;
1607 } else {
1608 if(mCurrentFrame.drop[i]) {
1609 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001610 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301611 continue;
1612 } else if(updatingLayersAbove <= 0) {
1613 batchCount++;
1614 batchEnd = i;
1615 i++;
1616 continue;
1617 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1618
1619 // We have a valid updating layer already. If layer-i not
1620 // have overlapping with all updating layers in between
1621 // batch-start and i, then we can add layer i to batch.
1622 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1623 batchCount++;
1624 batchEnd = i;
1625 i++;
1626 continue;
1627 } else if(canPushBatchToTop(list, batchStart, i)) {
1628 //If All the non-updating layers with in this batch
1629 //does not have intersection with the updating layers
1630 //above in z-order, then we can safely move the batch to
1631 //higher z-order. Increment fbZ as it is moving up.
1632 if( firstZReverseIndex < 0) {
1633 firstZReverseIndex = i;
1634 }
1635 batchCount++;
1636 batchEnd = i;
1637 fbZ += updatingLayersAbove;
1638 i++;
1639 updatingLayersAbove = 0;
1640 continue;
1641 } else {
1642 //both failed.start the loop again from here.
1643 if(firstZReverseIndex >= 0) {
1644 i = firstZReverseIndex;
1645 }
1646 break;
1647 }
1648 }
1649 }
1650 }
1651 if(batchCount > maxBatchCount) {
1652 maxBatchCount = batchCount;
1653 maxBatchStart = batchStart;
1654 maxBatchEnd = batchEnd;
1655 fbZOrder = fbZ;
1656 }
1657 }
1658 return fbZOrder;
1659}
1660
1661bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1662 hwc_display_contents_1_t* list) {
1663 /* Idea is to keep as many non-updating(cached) layers in FB and
1664 * send rest of them through MDP. This is done in 2 steps.
1665 * 1. Find the maximum contiguous batch of non-updating layers.
1666 * 2. See if we can improve this batch size for caching by adding
1667 * opaque layers around the batch, if they don't have
1668 * any overlapping with the updating layers in between.
1669 * NEVER mark an updating layer for caching.
1670 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001671
1672 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001673 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001674 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301675 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001676
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001677 /* Nothing is cached. No batching needed */
1678 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001679 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001680 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001681
1682 /* No MDP comp layers, try to use other comp modes */
1683 if(mCurrentFrame.mdpCount == 0) {
1684 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001685 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301687 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001688
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301689 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001690 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001691 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001692 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301693 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001694 if(!mCurrentFrame.drop[i]){
1695 //If an unsupported layer is being attempted to
1696 //be pulled out we should fail
1697 if(not isSupportedForMDPComp(ctx, layer)) {
1698 return false;
1699 }
1700 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001701 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001702 }
1703 }
1704
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301705 // update the frame data
1706 mCurrentFrame.fbZ = fbZ;
1707 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001708 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001709 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710
1711 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301712 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001713
1714 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001715}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001716
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001717void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001718 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001719 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001720 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001721
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001722 for(int i = 0; i < numAppLayers; i++) {
1723 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001724 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001725 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001726 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001728 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001729 }
1730 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001731
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001732 frame.fbCount = fbCount;
1733 frame.mdpCount = frame.layerCount - frame.fbCount
1734 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001735
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001736 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1737 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001738}
1739
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001740// drop other non-AIV layers from external display list.
1741void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001742 hwc_display_contents_1_t* list) {
1743 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1744 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001745 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001746 mCurrentFrame.dropCount++;
1747 mCurrentFrame.drop[i] = true;
1748 }
1749 }
1750 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1751 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1752 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1753 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1754 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1755 mCurrentFrame.dropCount);
1756}
1757
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001758void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001759 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001760 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1761 for(int index = 0;index < nYuvCount; index++){
1762 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1763 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1764
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001765 if(mCurrentFrame.drop[nYuvIndex]) {
1766 continue;
1767 }
1768
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001769 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001770 if(!frame.isFBComposed[nYuvIndex]) {
1771 frame.isFBComposed[nYuvIndex] = true;
1772 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001773 }
1774 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001775 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001776 private_handle_t *hnd = (private_handle_t *)layer->handle;
1777 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001778 frame.isFBComposed[nYuvIndex] = false;
1779 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001780 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001781 }
1782 }
1783 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001784
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001785 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1786 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001787}
1788
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001789void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1790 hwc_display_contents_1_t* list) {
1791 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1792 for(int index = 0;index < nSecureRGBCount; index++){
1793 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1794 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1795
1796 if(!isSecureRGBDoable(ctx, layer)) {
1797 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1798 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1799 mCurrentFrame.fbCount++;
1800 }
1801 } else {
1802 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1803 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1804 mCurrentFrame.fbCount--;
1805 }
1806 }
1807 }
1808
1809 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1810 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1811 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1812 mCurrentFrame.fbCount);
1813}
1814
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001815hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1816 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001817 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001818
1819 /* Update only the region of FB needed for composition */
1820 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1821 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1822 hwc_layer_1_t* layer = &list->hwLayers[i];
1823 hwc_rect_t dst = layer->displayFrame;
1824 fbRect = getUnion(fbRect, dst);
1825 }
1826 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001827 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001828 return fbRect;
1829}
1830
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001831bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1832 hwc_display_contents_1_t* list) {
1833
1834 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001835 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001836 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1837 return false;
1838 }
1839
1840 //Limitations checks
1841 if(!hwLimitationsCheck(ctx, list)) {
1842 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1843 return false;
1844 }
1845
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001846 //Configure framebuffer first if applicable
1847 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001848 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001849 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1850 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001851 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1852 __FUNCTION__);
1853 return false;
1854 }
1855 }
1856
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001857 mCurrentFrame.map();
1858
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001859 if(!allocLayerPipes(ctx, list)) {
1860 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001861 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001862 }
1863
1864 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001865 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001866 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001867 int mdpIndex = mCurrentFrame.layerToMDP[index];
1868 hwc_layer_1_t* layer = &list->hwLayers[index];
1869
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301870 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1871 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1872 mdpNextZOrder++;
1873 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001874 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1875 cur_pipe->zOrder = mdpNextZOrder++;
1876
radhakrishnac9a67412013-09-25 17:40:42 +05301877 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301878 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301879 if(configure4k2kYuv(ctx, layer,
1880 mCurrentFrame.mdpToLayer[mdpIndex])
1881 != 0 ){
1882 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1883 for layer %d",__FUNCTION__, index);
1884 return false;
1885 }
1886 else{
1887 mdpNextZOrder++;
1888 }
1889 continue;
1890 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001891 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1892 mdpNextZOrder++;
1893 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001894 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1895 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301896 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001897 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001898 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001899 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001900 }
1901
Saurabh Shaha36be922013-12-16 18:18:39 -08001902 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1903 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1904 ,__FUNCTION__, mDpy);
1905 return false;
1906 }
1907
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001908 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001909 return true;
1910}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001911
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001912bool MDPComp::resourceCheck(hwc_context_t* ctx,
1913 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001914 const bool fbUsed = mCurrentFrame.fbCount;
1915 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1916 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1917 return false;
1918 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001919
1920 //Will benefit cases where a video has non-updating background.
1921 if((mDpy > HWC_DISPLAY_PRIMARY) and
1922 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1923 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1924 return false;
1925 }
1926
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001927 // Init rotCount to number of rotate sessions used by other displays
1928 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1929 // Count the number of rotator sessions required for current display
1930 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1931 if(!mCurrentFrame.isFBComposed[index]) {
1932 hwc_layer_1_t* layer = &list->hwLayers[index];
1933 private_handle_t *hnd = (private_handle_t *)layer->handle;
1934 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1935 rotCount++;
1936 }
1937 }
1938 }
1939 // if number of layers to rotate exceeds max rotator sessions, bail out.
1940 if(rotCount > RotMgr::MAX_ROT_SESS) {
1941 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1942 __FUNCTION__, mDpy);
1943 return false;
1944 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001945 return true;
1946}
1947
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301948bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1949 hwc_display_contents_1_t* list) {
1950
1951 //A-family hw limitation:
1952 //If a layer need alpha scaling, MDP can not support.
1953 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1954 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1955 if(!mCurrentFrame.isFBComposed[i] &&
1956 isAlphaScaled( &list->hwLayers[i])) {
1957 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1958 return false;
1959 }
1960 }
1961 }
1962
1963 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1964 //If multiple layers requires downscaling and also they are overlapping
1965 //fall back to GPU since MDSS can not handle it.
1966 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1967 qdutils::MDPVersion::getInstance().is8x26()) {
1968 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1969 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1970 if(!mCurrentFrame.isFBComposed[i] &&
1971 isDownscaleRequired(botLayer)) {
1972 //if layer-i is marked for MDP and needs downscaling
1973 //check if any MDP layer on top of i & overlaps with layer-i
1974 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1975 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1976 if(!mCurrentFrame.isFBComposed[j] &&
1977 isDownscaleRequired(topLayer)) {
1978 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1979 topLayer->displayFrame);
1980 if(isValidRect(r))
1981 return false;
1982 }
1983 }
1984 }
1985 }
1986 }
1987 return true;
1988}
1989
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001990// Checks only if videos or single layer(RGB) is updating
1991// which is used for setting dynamic fps or perf hint for single
1992// layer video playback
1993bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1994 hwc_display_contents_1_t* list) {
1995 bool support = false;
1996 FrameInfo frame;
1997 frame.reset(mCurrentFrame.layerCount);
1998 memset(&frame.drop, 0, sizeof(frame.drop));
1999 frame.dropCount = 0;
2000 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
2001 updateLayerCache(ctx, list, frame);
2002 updateYUV(ctx, list, false /*secure only*/, frame);
2003 // There are only updating YUV layers or there is single RGB
2004 // Layer(Youtube)
2005 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2006 (frame.layerCount == 1)) {
2007 support = true;
2008 }
2009 return support;
2010}
2011
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302012void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2013 //For primary display, set the dynamic refreshrate
2014 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
2015 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302016 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2017 MDPVersion& mdpHw = MDPVersion::getInstance();
2018 if(sIdleFallBack) {
2019 //Set minimum panel refresh rate during idle timeout
2020 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002021 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302022 //Set the new fresh rate, if there is only one updating YUV layer
2023 //or there is one single RGB layer with this request
2024 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2025 }
2026 setRefreshRate(ctx, mDpy, refreshRate);
2027 }
2028}
2029
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002030int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002031 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002032 char property[PROPERTY_VALUE_MAX];
2033
Raj Kamal4393eaa2014-06-06 13:45:20 +05302034 if(!ctx || !list) {
2035 ALOGE("%s: Invalid context or list",__FUNCTION__);
2036 mCachedFrame.reset();
2037 return -1;
2038 }
2039
2040 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002041 if(mDpy == HWC_DISPLAY_PRIMARY) {
2042 sSimulationFlags = 0;
2043 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2044 int currentFlags = atoi(property);
2045 if(currentFlags != sSimulationFlags) {
2046 sSimulationFlags = currentFlags;
2047 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2048 sSimulationFlags, sSimulationFlags);
2049 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002050 }
2051 }
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002052
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302053 //reset old data
2054 mCurrentFrame.reset(numLayers);
2055 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2056 mCurrentFrame.dropCount = 0;
2057
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302058 //Do not cache the information for next draw cycle.
2059 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2060 ALOGI("%s: Unsupported layer count for mdp composition",
2061 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002062 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302063#ifdef DYNAMIC_FPS
2064 setDynRefreshRate(ctx, list);
2065#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002066 return -1;
2067 }
2068
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002069 // Detect the start of animation and fall back to GPU only once to cache
2070 // all the layers in FB and display FB content untill animation completes.
2071 if(ctx->listStats[mDpy].isDisplayAnimating) {
2072 mCurrentFrame.needsRedraw = false;
2073 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2074 mCurrentFrame.needsRedraw = true;
2075 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2076 }
2077 setMDPCompLayerFlags(ctx, list);
2078 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302079#ifdef DYNAMIC_FPS
2080 setDynRefreshRate(ctx, list);
2081#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002082 ret = -1;
2083 return ret;
2084 } else {
2085 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2086 }
2087
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302088 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2089 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2090
2091 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2092 mCurrentFrame.needsRedraw = false;
2093 setMDPCompLayerFlags(ctx, list);
2094 mCachedFrame.updateCounts(mCurrentFrame);
2095#ifdef DYNAMIC_FPS
2096 setDynRefreshRate(ctx, list);
2097#endif
2098 return -1;
2099
2100 }
2101
Saurabh Shahb39f8152013-08-22 10:21:44 -07002102 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002103 if(isFrameDoable(ctx)) {
2104 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002105 // if AIV Video mode is enabled, drop all non AIV layers from the
2106 // external display list.
2107 if(ctx->listStats[mDpy].mAIVVideoMode) {
2108 dropNonAIVLayers(ctx, list);
2109 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002110
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002111 // if tryFullFrame fails, try to push all video and secure RGB layers
2112 // to MDP for composition.
2113 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002114 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302115 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002116 setMDPCompLayerFlags(ctx, list);
2117 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002118 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002119 reset(ctx);
2120 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2121 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002122 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002123 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2124 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002125 }
2126 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302127 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2128 enablePartialUpdateForMDP3) {
2129 generateROI(ctx, list);
2130 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2131 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2132 }
2133 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002134 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2135 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002136 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002137 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002138
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002139 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002140 ALOGD("GEOMETRY change: %d",
2141 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002142 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002143 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002144 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002145 }
2146
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002147#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302148 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002149#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002150 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002151
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002152 mCachedFrame.cacheAll(list);
2153 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002154 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002155}
2156
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002157bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302158
2159 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302160 int mdpIndex = mCurrentFrame.layerToMDP[index];
2161 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2162 info.pipeInfo = new MdpYUVPipeInfo;
2163 info.rot = NULL;
2164 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302165
2166 pipe_info.lIndex = ovutils::OV_INVALID;
2167 pipe_info.rIndex = ovutils::OV_INVALID;
2168
Saurabh Shahc62f3982014-03-05 14:28:26 -08002169 Overlay::PipeSpecs pipeSpecs;
2170 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2171 pipeSpecs.needsScaling = true;
2172 pipeSpecs.dpy = mDpy;
2173 pipeSpecs.fb = false;
2174
2175 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302176 if(pipe_info.lIndex == ovutils::OV_INVALID){
2177 bRet = false;
2178 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2179 __FUNCTION__);
2180 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002181 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302182 if(pipe_info.rIndex == ovutils::OV_INVALID){
2183 bRet = false;
2184 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2185 __FUNCTION__);
2186 }
2187 return bRet;
2188}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002189
2190int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2191 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002192 if (ctx->mPtorInfo.isActive()) {
2193 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002194 if (fd < 0) {
2195 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002196 }
2197 }
2198 return fd;
2199}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002200//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002201
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002202void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302203 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002204 //If 4k2k Yuv layer split is possible, and if
2205 //fbz is above 4k2k layer, increment fb zorder by 1
2206 //as we split 4k2k layer and increment zorder for right half
2207 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002208 if(!ctx)
2209 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002210 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302211 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2212 index++) {
2213 if(!mCurrentFrame.isFBComposed[index]) {
2214 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2215 mdpNextZOrder++;
2216 }
2217 mdpNextZOrder++;
2218 hwc_layer_1_t* layer = &list->hwLayers[index];
2219 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302220 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302221 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2222 mCurrentFrame.fbZ += 1;
2223 mdpNextZOrder++;
2224 //As we split 4kx2k yuv layer and program to 2 VG pipes
2225 //(if available) increase mdpcount by 1.
2226 mCurrentFrame.mdpCount++;
2227 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002228 }
2229 }
2230 }
radhakrishnac9a67412013-09-25 17:40:42 +05302231}
2232
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002233/*
2234 * Configures pipe(s) for MDP composition
2235 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002236int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002237 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002238 MdpPipeInfoNonSplit& mdp_info =
2239 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302240 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002241 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002242 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002243
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002244 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2245 __FUNCTION__, layer, zOrder, dest);
2246
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002247 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002248 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002249}
2250
Saurabh Shah88e4d272013-09-03 13:31:29 -07002251bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002252 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002253 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2254 formatType++) {
2255 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
2256 if(mCurrentFrame.isFBComposed[index]) continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002257
Saurabh Shah8cc77712015-03-31 10:48:51 -07002258 hwc_layer_1_t* layer = &list->hwLayers[index];
2259 private_handle_t *hnd = (private_handle_t *)layer->handle;
2260 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
radhakrishnac9a67412013-09-25 17:40:42 +05302261 continue;
Saurabh Shah8cc77712015-03-31 10:48:51 -07002262 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
2263 continue;
2264
2265 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2266 if(allocSplitVGPipes(ctx, index)){
2267 continue;
2268 }
radhakrishnac9a67412013-09-25 17:40:42 +05302269 }
radhakrishnac9a67412013-09-25 17:40:42 +05302270
Saurabh Shah8cc77712015-03-31 10:48:51 -07002271 int mdpIndex = mCurrentFrame.layerToMDP[index];
2272 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2273 info.pipeInfo = new MdpPipeInfoNonSplit;
2274 info.rot = NULL;
2275 MdpPipeInfoNonSplit& pipe_info =
2276 *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002277
Saurabh Shah8cc77712015-03-31 10:48:51 -07002278 Overlay::PipeSpecs pipeSpecs;
2279 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2280 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2281 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2282 (qdutils::MDPVersion::getInstance().is8x26() and
2283 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2284 pipeSpecs.dpy = mDpy;
2285 pipeSpecs.fb = false;
2286 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002287
Saurabh Shah8cc77712015-03-31 10:48:51 -07002288 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahc62f3982014-03-05 14:28:26 -08002289
Saurabh Shah8cc77712015-03-31 10:48:51 -07002290 if(pipe_info.index == ovutils::OV_INVALID) {
2291 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2292 "format type %d", __FUNCTION__, index, formatType);
2293 return false;
2294 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002295 }
2296 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002297 return true;
2298}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002299
radhakrishnac9a67412013-09-25 17:40:42 +05302300int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2301 PipeLayerPair& PipeLayerPair) {
2302 MdpYUVPipeInfo& mdp_info =
2303 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2304 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302305 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302306 eDest lDest = mdp_info.lIndex;
2307 eDest rDest = mdp_info.rIndex;
2308
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002309 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302310 lDest, rDest, &PipeLayerPair.rot);
2311}
2312
Saurabh Shah88e4d272013-09-03 13:31:29 -07002313bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002314
Raj Kamal4393eaa2014-06-06 13:45:20 +05302315 if(!isEnabled() or !mModeOn) {
2316 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302317 return true;
2318 }
2319
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002320 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002321 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002322
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002323 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2324 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002325 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002326 if(mCurrentFrame.isFBComposed[i]) continue;
2327
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002328 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002329 private_handle_t *hnd = (private_handle_t *)layer->handle;
2330 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002331 if (!(layer->flags & HWC_COLOR_FILL)) {
2332 ALOGE("%s handle null", __FUNCTION__);
2333 return false;
2334 }
2335 // No PLAY for Color layer
2336 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2337 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002338 }
2339
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002340 int mdpIndex = mCurrentFrame.layerToMDP[i];
2341
Raj Kamal389d6e32014-08-04 14:43:24 +05302342 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302343 {
2344 MdpYUVPipeInfo& pipe_info =
2345 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2346 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2347 ovutils::eDest indexL = pipe_info.lIndex;
2348 ovutils::eDest indexR = pipe_info.rIndex;
2349 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302350 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302351 if(rot) {
2352 rot->queueBuffer(fd, offset);
2353 fd = rot->getDstMemId();
2354 offset = rot->getDstOffset();
2355 }
2356 if(indexL != ovutils::OV_INVALID) {
2357 ovutils::eDest destL = (ovutils::eDest)indexL;
2358 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2359 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2360 if (!ov.queueBuffer(fd, offset, destL)) {
2361 ALOGE("%s: queueBuffer failed for display:%d",
2362 __FUNCTION__, mDpy);
2363 return false;
2364 }
2365 }
2366
2367 if(indexR != ovutils::OV_INVALID) {
2368 ovutils::eDest destR = (ovutils::eDest)indexR;
2369 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2370 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2371 if (!ov.queueBuffer(fd, offset, destR)) {
2372 ALOGE("%s: queueBuffer failed for display:%d",
2373 __FUNCTION__, mDpy);
2374 return false;
2375 }
2376 }
2377 }
2378 else{
2379 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002380 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302381 ovutils::eDest dest = pipe_info.index;
2382 if(dest == ovutils::OV_INVALID) {
2383 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002384 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302385 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002386
radhakrishnac9a67412013-09-25 17:40:42 +05302387 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2388 continue;
2389 }
2390
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002391 int fd = hnd->fd;
2392 uint32_t offset = (uint32_t)hnd->offset;
2393 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2394 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002395 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002396 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002397 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002398 }
2399
radhakrishnac9a67412013-09-25 17:40:42 +05302400 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2401 using pipe: %d", __FUNCTION__, layer,
2402 hnd, dest );
2403
radhakrishnac9a67412013-09-25 17:40:42 +05302404 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2405 if(rot) {
2406 if(!rot->queueBuffer(fd, offset))
2407 return false;
2408 fd = rot->getDstMemId();
2409 offset = rot->getDstOffset();
2410 }
2411
2412 if (!ov.queueBuffer(fd, offset, dest)) {
2413 ALOGE("%s: queueBuffer failed for display:%d ",
2414 __FUNCTION__, mDpy);
2415 return false;
2416 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002417 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002418
2419 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002420 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002421 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002422}
2423
Saurabh Shah88e4d272013-09-03 13:31:29 -07002424//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002425
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002426void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302427 hwc_display_contents_1_t* list){
2428 //if 4kx2k yuv layer is totally present in either in left half
2429 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302430 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302431 if(mCurrentFrame.fbZ >= 0) {
2432 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2433 index++) {
2434 if(!mCurrentFrame.isFBComposed[index]) {
2435 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2436 mdpNextZOrder++;
2437 }
2438 mdpNextZOrder++;
2439 hwc_layer_1_t* layer = &list->hwLayers[index];
2440 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002441 if(isYUVSplitNeeded(hnd) ||
2442 (needs3DComposition(ctx,mDpy) &&
2443 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302444 hwc_rect_t dst = layer->displayFrame;
2445 if((dst.left > lSplit) || (dst.right < lSplit)) {
2446 mCurrentFrame.mdpCount += 1;
2447 }
2448 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2449 mCurrentFrame.fbZ += 1;
2450 mdpNextZOrder++;
2451 }
2452 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002453 }
radhakrishnac9a67412013-09-25 17:40:42 +05302454 }
2455}
2456
Saurabh Shah88e4d272013-09-03 13:31:29 -07002457bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002458 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002459
Saurabh Shahc62f3982014-03-05 14:28:26 -08002460 const int lSplit = getLeftSplit(ctx, mDpy);
2461 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002462 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002463 pipe_info.lIndex = ovutils::OV_INVALID;
2464 pipe_info.rIndex = ovutils::OV_INVALID;
2465
Saurabh Shahc62f3982014-03-05 14:28:26 -08002466 Overlay::PipeSpecs pipeSpecs;
2467 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2468 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2469 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2470 pipeSpecs.dpy = mDpy;
2471 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2472 pipeSpecs.fb = false;
2473
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002474 // Acquire pipe only for the updating half
2475 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2476 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2477
2478 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002479 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002480 if(pipe_info.lIndex == ovutils::OV_INVALID)
2481 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002482 }
2483
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002484 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002485 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2486 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002487 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002488 return false;
2489 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002490
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002491 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002492}
2493
Saurabh Shah88e4d272013-09-03 13:31:29 -07002494bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002495 hwc_display_contents_1_t* list) {
Saurabh Shah8cc77712015-03-31 10:48:51 -07002496 for(uint32_t formatType = FORMAT_YUV; formatType < FORMAT_MAX;
2497 formatType++) {
2498 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
2499 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002500
Saurabh Shah8cc77712015-03-31 10:48:51 -07002501 hwc_layer_1_t* layer = &list->hwLayers[index];
2502 private_handle_t *hnd = (private_handle_t *)layer->handle;
2503 if(formatType == FORMAT_YUV && !isYuvBuffer(hnd))
2504 continue;
2505 if(formatType == FORMAT_RGB && isYuvBuffer(hnd))
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002506 continue;
2507
Saurabh Shah8cc77712015-03-31 10:48:51 -07002508 hwc_rect_t dst = layer->displayFrame;
2509 const int lSplit = getLeftSplit(ctx, mDpy);
2510 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2511 if((dst.left > lSplit)||(dst.right < lSplit)){
2512 if(allocSplitVGPipes(ctx, index)){
2513 continue;
2514 }
2515 }
2516 }
2517 //XXX: Check for forced 2D composition
2518 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2519 if(allocSplitVGPipes(ctx,index))
2520 continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002521
Saurabh Shah8cc77712015-03-31 10:48:51 -07002522 int mdpIndex = mCurrentFrame.layerToMDP[index];
2523 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2524 info.pipeInfo = new MdpPipeInfoSplit;
2525 info.rot = NULL;
2526 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
2527
2528 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2529 ALOGD_IF(isDebug(), "%s: Unable to get pipe for layer %d of "\
2530 "format type %d", __FUNCTION__, index, formatType);
2531 return false;
2532 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002533 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002534 }
2535 return true;
2536}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002537
radhakrishnac9a67412013-09-25 17:40:42 +05302538int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2539 PipeLayerPair& PipeLayerPair) {
2540 const int lSplit = getLeftSplit(ctx, mDpy);
2541 hwc_rect_t dst = layer->displayFrame;
2542 if((dst.left > lSplit)||(dst.right < lSplit)){
2543 MdpYUVPipeInfo& mdp_info =
2544 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2545 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302546 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302547 eDest lDest = mdp_info.lIndex;
2548 eDest rDest = mdp_info.rIndex;
2549
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002550 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302551 lDest, rDest, &PipeLayerPair.rot);
2552 }
2553 else{
2554 return configure(ctx, layer, PipeLayerPair);
2555 }
2556}
2557
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002558/*
2559 * Configures pipe(s) for MDP composition
2560 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002561int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002562 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002563 MdpPipeInfoSplit& mdp_info =
2564 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002565 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302566 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002567 eDest lDest = mdp_info.lIndex;
2568 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002569
2570 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002571 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002572
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002573 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002574 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002575}
2576
Saurabh Shah88e4d272013-09-03 13:31:29 -07002577bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002578
Raj Kamal4393eaa2014-06-06 13:45:20 +05302579 if(!isEnabled() or !mModeOn) {
2580 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302581 return true;
2582 }
2583
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002584 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002585 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002586
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002587 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2588 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002589 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002590 if(mCurrentFrame.isFBComposed[i]) continue;
2591
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002592 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002593 private_handle_t *hnd = (private_handle_t *)layer->handle;
2594 if(!hnd) {
2595 ALOGE("%s handle null", __FUNCTION__);
2596 return false;
2597 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002598
2599 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2600 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002601 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002602
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002603 int mdpIndex = mCurrentFrame.layerToMDP[i];
2604
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002605 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2606 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302607 {
2608 MdpYUVPipeInfo& pipe_info =
2609 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2610 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2611 ovutils::eDest indexL = pipe_info.lIndex;
2612 ovutils::eDest indexR = pipe_info.rIndex;
2613 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302614 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302615 if(rot) {
2616 rot->queueBuffer(fd, offset);
2617 fd = rot->getDstMemId();
2618 offset = rot->getDstOffset();
2619 }
2620 if(indexL != ovutils::OV_INVALID) {
2621 ovutils::eDest destL = (ovutils::eDest)indexL;
2622 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2623 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2624 if (!ov.queueBuffer(fd, offset, destL)) {
2625 ALOGE("%s: queueBuffer failed for display:%d",
2626 __FUNCTION__, mDpy);
2627 return false;
2628 }
2629 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002630
radhakrishnac9a67412013-09-25 17:40:42 +05302631 if(indexR != ovutils::OV_INVALID) {
2632 ovutils::eDest destR = (ovutils::eDest)indexR;
2633 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2634 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2635 if (!ov.queueBuffer(fd, offset, destR)) {
2636 ALOGE("%s: queueBuffer failed for display:%d",
2637 __FUNCTION__, mDpy);
2638 return false;
2639 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002640 }
2641 }
radhakrishnac9a67412013-09-25 17:40:42 +05302642 else{
2643 MdpPipeInfoSplit& pipe_info =
2644 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2645 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002646
radhakrishnac9a67412013-09-25 17:40:42 +05302647 ovutils::eDest indexL = pipe_info.lIndex;
2648 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002649
radhakrishnac9a67412013-09-25 17:40:42 +05302650 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002651 uint32_t offset = (uint32_t)hnd->offset;
2652 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2653 if (!mDpy && (index != -1)) {
2654 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2655 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002656 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002657 }
radhakrishnac9a67412013-09-25 17:40:42 +05302658
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002659 if(ctx->mAD->draw(ctx, fd, offset)) {
2660 fd = ctx->mAD->getDstFd();
2661 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002662 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002663
radhakrishnac9a67412013-09-25 17:40:42 +05302664 if(rot) {
2665 rot->queueBuffer(fd, offset);
2666 fd = rot->getDstMemId();
2667 offset = rot->getDstOffset();
2668 }
2669
2670 //************* play left mixer **********
2671 if(indexL != ovutils::OV_INVALID) {
2672 ovutils::eDest destL = (ovutils::eDest)indexL;
2673 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2674 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2675 if (!ov.queueBuffer(fd, offset, destL)) {
2676 ALOGE("%s: queueBuffer failed for left mixer",
2677 __FUNCTION__);
2678 return false;
2679 }
2680 }
2681
2682 //************* play right mixer **********
2683 if(indexR != ovutils::OV_INVALID) {
2684 ovutils::eDest destR = (ovutils::eDest)indexR;
2685 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2686 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2687 if (!ov.queueBuffer(fd, offset, destR)) {
2688 ALOGE("%s: queueBuffer failed for right mixer",
2689 __FUNCTION__);
2690 return false;
2691 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002692 }
2693 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002694
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002695 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2696 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002697
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002698 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002699}
Saurabh Shahab47c692014-02-12 18:45:57 -08002700
2701//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002702
2703bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2704 hwc_display_contents_1_t* list) {
2705 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2706 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2707
2708 for(int i = numAppLayers - 1; i >= 0; i--) {
2709 if(!isValidRect(visibleRect)) {
2710 mCurrentFrame.drop[i] = true;
2711 mCurrentFrame.dropCount++;
2712 continue;
2713 }
2714
2715 const hwc_layer_1_t* layer = &list->hwLayers[i];
2716 hwc_rect_t dstRect = layer->displayFrame;
2717 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2718
2719 if(!isValidRect(res)) {
2720 mCurrentFrame.drop[i] = true;
2721 mCurrentFrame.dropCount++;
2722 } else {
2723 /* Reset frame ROI when any layer which needs scaling also needs ROI
2724 * cropping */
2725 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2726 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2727 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2728 mCurrentFrame.dropCount = 0;
2729 return false;
2730 }
2731
2732 /* deduct any opaque region from visibleRect */
2733 if (layer->blending == HWC_BLENDING_NONE &&
2734 layer->planeAlpha == 0xFF)
2735 visibleRect = deductRect(visibleRect, res);
2736 }
2737 }
2738 return true;
2739}
2740
2741/*
2742 * HW Limitation: ping pong split can always split the ping pong output
2743 * equally across two DSI's. So the ROI programmed should be of equal width
2744 * for both the halves
2745 */
2746void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2747 hwc_display_contents_1_t* list) {
2748 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2749
2750
2751 if(!canPartialUpdate(ctx, list))
2752 return;
2753
2754 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2755 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2756 (int)ctx->dpyAttr[mDpy].yres};
2757
2758 for(int index = 0; index < numAppLayers; index++ ) {
2759 hwc_layer_1_t* layer = &list->hwLayers[index];
2760
2761 // If we have a RGB layer which needs rotation, no partial update
2762 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2763 return;
2764
2765 if ((mCachedFrame.hnd[index] != layer->handle) ||
2766 isYuvBuffer((private_handle_t *)layer->handle)) {
2767 hwc_rect_t dst = layer->displayFrame;
2768 hwc_rect_t updatingRect = dst;
2769
2770#ifdef QCOM_BSP
2771 if(!needsScaling(layer) && !layer->transform)
2772 {
2773 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2774 int x_off = dst.left - src.left;
2775 int y_off = dst.top - src.top;
2776 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2777 }
2778#endif
2779
2780 roi = getUnion(roi, updatingRect);
2781 }
2782 }
2783
2784 /* No layer is updating. Still SF wants a refresh.*/
2785 if(!isValidRect(roi))
2786 return;
2787
2788 roi = expandROIFromMidPoint(roi, fullFrame);
2789
2790 hwc_rect lFrame = fullFrame;
2791 lFrame.right /= 2;
2792 hwc_rect lRoi = getIntersection(roi, lFrame);
2793
2794 // Align ROI coordinates to panel restrictions
2795 lRoi = getSanitizeROI(lRoi, lFrame);
2796
2797 hwc_rect rFrame = fullFrame;
2798 rFrame.left = lFrame.right;
2799 hwc_rect rRoi = getIntersection(roi, rFrame);
2800
2801 // Align ROI coordinates to panel restrictions
2802 rRoi = getSanitizeROI(rRoi, rFrame);
2803
2804 roi = getUnion(lRoi, rRoi);
2805
2806 ctx->listStats[mDpy].lRoi = roi;
2807 if(!validateAndApplyROI(ctx, list))
2808 resetROI(ctx, mDpy);
2809
2810 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2811 __FUNCTION__,
2812 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2813 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2814 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2815 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2816}
2817
Saurabh Shahab47c692014-02-12 18:45:57 -08002818bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002819 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002820 private_handle_t *hnd = (private_handle_t *)layer->handle;
2821 hwc_rect_t dst = layer->displayFrame;
2822 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2823 pipe_info.lIndex = ovutils::OV_INVALID;
2824 pipe_info.rIndex = ovutils::OV_INVALID;
2825
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002826 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2827 trimAgainstROI(ctx,crop, dst);
2828
Saurabh Shahab47c692014-02-12 18:45:57 -08002829 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2830 //should have a higher priority than the right one. Pipe priorities are
2831 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002832
Saurabh Shahc62f3982014-03-05 14:28:26 -08002833 Overlay::PipeSpecs pipeSpecs;
2834 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2835 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2836 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2837 pipeSpecs.dpy = mDpy;
2838 pipeSpecs.fb = false;
2839
Saurabh Shahab47c692014-02-12 18:45:57 -08002840 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002841 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002842 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002843 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002844 }
2845
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002846 /* Use 2 pipes IF
2847 a) Layer's crop width is > 2048 or
2848 b) Layer's dest width > 2048 or
2849 c) On primary, driver has indicated with caps to split always. This is
2850 based on an empirically derived value of panel height. Applied only
2851 if the layer's width is > mixer's width
2852 */
2853
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302854 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002855 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302856 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002857 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2858 const uint32_t dstWidth = dst.right - dst.left;
2859 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002860 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002861 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002862 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002863 crop.bottom - crop.top;
2864 //Approximation to actual clock, ignoring the common factors in pipe and
2865 //mixer cases like line_time
2866 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2867 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002868
Saurabh Shah05f4e222015-02-05 14:36:22 -08002869 const uint32_t downscale = getRotDownscale(ctx, layer);
2870 if(downscale) {
2871 cropWidth /= downscale;
2872 cropHeight /= downscale;
2873 }
2874
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002875 if(dstWidth > mdpHw.getMaxPipeWidth() or
2876 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002877 (primarySplitAlways and
2878 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002879 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002880 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002881 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002882 }
2883
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002884 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2885 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002886 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002887 }
2888 }
2889
2890 return true;
2891}
2892
Saurabh Shahab47c692014-02-12 18:45:57 -08002893int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2894 PipeLayerPair& PipeLayerPair) {
2895 private_handle_t *hnd = (private_handle_t *)layer->handle;
2896 if(!hnd) {
2897 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2898 return -1;
2899 }
2900 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2901 MdpPipeInfoSplit& mdp_info =
2902 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2903 Rotator **rot = &PipeLayerPair.rot;
2904 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002905 eDest lDest = mdp_info.lIndex;
2906 eDest rDest = mdp_info.rIndex;
2907 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2908 hwc_rect_t dst = layer->displayFrame;
2909 int transform = layer->transform;
2910 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002911 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002912 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002913 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002914 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08002915
2916 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2917 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2918
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002919 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2920 /* MDP driver crops layer coordinates against ROI in Non-Split
2921 * and Split MDP comp. But HWC needs to crop them for source split.
2922 * Reason: 1) Source split is efficient only when the final effective
2923 * load is distributed evenly across mixers.
2924 * 2) We have to know the effective width of the layer that
2925 * the ROI needs to find the no. of pipes the layer needs.
2926 */
2927 trimAgainstROI(ctx, crop, dst);
2928 }
2929
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002930 if(needs3DComposition(ctx, mDpy) &&
2931 get3DFormat(hnd) != HAL_NO_3D){
2932 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
2933 rDest, &PipeLayerPair.rot);
2934 }
2935
Saurabh Shahab47c692014-02-12 18:45:57 -08002936 // Handle R/B swap
2937 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2938 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2939 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2940 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2941 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2942 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002943 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002944 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2945 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002946 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002947 /* Calculate the external display position based on MDP downscale,
2948 ActionSafe, and extorientation features. */
2949 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002950
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002951 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002952 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002953
2954 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2955 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002956 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002957 }
2958
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002959 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002960 (*rot) = ctx->mRotMgr->getNext();
2961 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002962 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002963 //If the video is using a single pipe, enable BWC
2964 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002965 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2966 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002967 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002968 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002969 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002970 ALOGE("%s: configRotator failed!", __FUNCTION__);
2971 return -1;
2972 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002973 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002974 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002975 }
2976
2977 //If 2 pipes being used, divide layer into half, crop and dst
2978 hwc_rect_t cropL = crop;
2979 hwc_rect_t cropR = crop;
2980 hwc_rect_t dstL = dst;
2981 hwc_rect_t dstR = dst;
2982 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2983 cropL.right = (crop.right + crop.left) / 2;
2984 cropR.left = cropL.right;
2985 sanitizeSourceCrop(cropL, cropR, hnd);
2986
Saurabh Shahb729b192014-08-15 18:04:24 -07002987 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002988 //Swap crops on H flip since 2 pipes are being used
2989 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2990 hwc_rect_t tmp = cropL;
2991 cropL = cropR;
2992 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002993 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002994 }
2995
Saurabh Shahb729b192014-08-15 18:04:24 -07002996 //cropSwap trick: If the src and dst widths are both odd, let us say
2997 //2507, then splitting both into half would cause left width to be 1253
2998 //and right 1254. If crop is swapped because of H flip, this will cause
2999 //left crop width to be 1254, whereas left dst width remains 1253, thus
3000 //inducing a scaling that is unaccounted for. To overcome that we add 1
3001 //to the dst width if there is a cropSwap. So if the original width was
3002 //2507, the left dst width will be 1254. Even if the original width was
3003 //even for ex: 2508, the left dst width will still remain 1254.
3004 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08003005 dstR.left = dstL.right;
3006 }
3007
3008 //For the mdp, since either we are pre-rotating or MDP does flips
3009 orient = OVERLAY_TRANSFORM_0;
3010 transform = 0;
3011
3012 //configure left pipe
3013 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003014 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003015 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
3016 (ovutils::eBlending) getBlending(layer->blending));
3017
3018 if(configMdp(ctx->mOverlay, pargL, orient,
3019 cropL, dstL, metadata, lDest) < 0) {
3020 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
3021 return -1;
3022 }
3023 }
3024
3025 //configure right pipe
3026 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003027 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003028 static_cast<eRotFlags>(rotFlags),
3029 layer->planeAlpha,
3030 (ovutils::eBlending) getBlending(layer->blending));
3031 if(configMdp(ctx->mOverlay, pargR, orient,
3032 cropR, dstR, metadata, rDest) < 0) {
3033 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3034 return -1;
3035 }
3036 }
3037
3038 return 0;
3039}
3040
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003041bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3042 Locker::Autolock _l(ctx->mDrawLock);
3043 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3044 char path[MAX_SYSFS_FILE_PATH];
3045 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3046 int fd = open(path, O_RDONLY);
3047 if(fd < 0) {
3048 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3049 return -1;
3050 }
3051 char value[4];
3052 ssize_t size_read = read(fd, value, sizeof(value)-1);
3053 if(size_read <= 0) {
3054 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3055 close(fd);
3056 return -1;
3057 }
3058 close(fd);
3059 value[size_read] = '\0';
3060 return atoi(value);
3061}
3062
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003063int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3064 Locker::Autolock _l(ctx->mDrawLock);
3065 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3066 char path[MAX_SYSFS_FILE_PATH];
3067 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3068 int fd = open(path, O_WRONLY);
3069 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003070 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003071 return -1;
3072 }
3073 char value[4];
3074 snprintf(value, sizeof(value), "%d", (int)enable);
3075 ssize_t ret = write(fd, value, strlen(value));
3076 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003077 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003078 close(fd);
3079 return -1;
3080 }
3081 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003082 return 0;
3083}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003084
3085bool MDPComp::loadPerfLib() {
3086 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3087 bool success = false;
3088 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3089 ALOGE("vendor library not set in ro.vendor.extension_library");
3090 return false;
3091 }
3092
3093 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3094 if(sLibPerfHint) {
3095 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3096 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3097 if (!sPerfLockAcquire || !sPerfLockRelease) {
3098 ALOGE("Failed to load symbols for perfLock");
3099 dlclose(sLibPerfHint);
3100 sLibPerfHint = NULL;
3101 return false;
3102 }
3103 success = true;
3104 ALOGI("Successfully Loaded perf hint API's");
3105 } else {
3106 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3107 }
3108 return success;
3109}
3110
3111void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3112 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3113 return;
3114 }
3115 static int count = sPerfHintWindow;
3116 static int perflockFlag = 0;
3117
3118 /* Send hint to mpctl when single layer is updated
3119 * for a successful number of windows. Hint release
3120 * happens immediately upon multiple layer update.
3121 */
3122 if (onlyVideosUpdating(ctx, list)) {
3123 if(count) {
3124 count--;
3125 }
3126 } else {
3127 if (perflockFlag) {
3128 perflockFlag = 0;
3129 sPerfLockRelease(sPerfLockHandle);
3130 }
3131 count = sPerfHintWindow;
3132 }
3133 if (count == 0 && !perflockFlag) {
3134 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3135 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3136 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003137 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003138 perflockFlag = 1;
3139 }
3140 }
3141}
3142
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003143}; //namespace
3144