blob: 009fbe0da0beb85ddd9f3e75a76afc5c66531191 [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 Shah88e4d272013-09-03 13:31:29 -070059MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070060 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
61 sSrcSplitEnabled = true;
62 return new MDPCompSrcSplit(dpy);
63 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070064 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080065 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070066 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080067}
68
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080069MDPComp::MDPComp(int dpy):mDpy(dpy){};
70
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070071void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080072{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070073 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
74 return;
75
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080076 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070077 (mDpy == 0) ? "\"PRIMARY\"" :
78 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070079 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
80 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080081 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
82 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
83 (mCurrentFrame.needsRedraw? "YES" : "NO"),
84 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070085 if(isDisplaySplit(ctx, mDpy)) {
86 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
87 "Right: [%d, %d, %d, %d] \n",
88 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
89 ctx->listStats[mDpy].lRoi.right,
90 ctx->listStats[mDpy].lRoi.bottom,
91 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
92 ctx->listStats[mDpy].rRoi.right,
93 ctx->listStats[mDpy].rRoi.bottom);
94 } else {
95 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
96 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
97 ctx->listStats[mDpy].lRoi.right,
98 ctx->listStats[mDpy].lRoi.bottom);
99 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800100 dumpsys_log(buf," --------------------------------------------- \n");
101 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
102 dumpsys_log(buf," --------------------------------------------- \n");
103 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
104 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
105 index,
106 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700107 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800108 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700109 (mCurrentFrame.drop[index] ? "DROP" :
110 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800111 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
112 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
113 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114}
115
116bool MDPComp::init(hwc_context_t *ctx) {
117
118 if(!ctx) {
119 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
120 return false;
121 }
122
Saurabh Shah59562ff2014-09-30 16:13:12 -0700123 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800124
125 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530126 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
127 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800128 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
129 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800130 sEnabled = true;
131 }
132
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700133 sEnableMixedMode = true;
134 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
135 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
136 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
137 sEnableMixedMode = false;
138 }
139
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700140 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
141
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800142 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700143 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700144 int val = atoi(property);
145 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700146 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800147 }
148
Saurabh Shahacec8e42014-11-25 11:07:04 -0800149 /* Maximum layers allowed to use MDP on secondary panels. If property
150 * doesn't exist, default to 1. Using the property it can be set to 0 or
151 * more.
152 */
153 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
154 int val = atoi(property);
155 sMaxSecLayers = (val >= 0) ? val : 1;
156 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
157 }
158
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400159 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700160 sIdleInvalidator = IdleInvalidator::getInstance();
161 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
162 delete sIdleInvalidator;
163 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400164 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800165 }
radhakrishnac9a67412013-09-25 17:40:42 +0530166
Saurabh Shah7c727642014-06-02 15:47:14 -0700167 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700168 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700169 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
170 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
171 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530172 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530173 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700174
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530175 bool defaultPTOR = false;
176 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
177 //8x16 and 8x39 targets by default
178 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
179 (qdutils::MDPVersion::getInstance().is8x16() ||
180 qdutils::MDPVersion::getInstance().is8x39())) {
181 defaultPTOR = true;
182 }
183
184 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
185 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700186 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
187 HWC_DISPLAY_PRIMARY);
188 }
189
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530190 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
191 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
192 enablePartialUpdateForMDP3 = true;
193 }
194
195 if(!enablePartialUpdateForMDP3 &&
196 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
197 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
198 enablePartialUpdateForMDP3 = true;
199 }
200
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800201 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
202
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800203 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
204 int val = atoi(property);
205 if(val > 0 && loadPerfLib()) {
206 sPerfHintWindow = val;
207 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
208 }
209 }
210
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700211 return true;
212}
213
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800214void MDPComp::reset(hwc_context_t *ctx) {
215 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700216 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800217 ctx->mOverlay->clear(mDpy);
218 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700219}
220
Raj Kamal4393eaa2014-06-06 13:45:20 +0530221void MDPComp::reset() {
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530222 mPrevModeOn = mModeOn;
Raj Kamal4393eaa2014-06-06 13:45:20 +0530223 mModeOn = false;
224}
225
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700226void MDPComp::timeout_handler(void *udata) {
227 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530228 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700229
230 if(!ctx) {
231 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
232 return;
233 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530234
235 ctx->mDrawLock.lock();
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530236
237 /* Handle timeout event only if the previous composition
238 on any display is MDP or MIXED*/
239 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
240 if(ctx->mMDPComp[i])
241 handleTimeout =
242 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
243 }
244
245 if(!handleTimeout) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800246 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530247 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800248 return;
249 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700250 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700251 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530252 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700253 return;
254 }
255 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530256 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700257 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700258 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700259}
260
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700261void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
262 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800263 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700264 if(value > maxSupported) {
265 ALOGW("%s: Input exceeds max value supported. Setting to"
266 "max value: %d", __FUNCTION__, maxSupported);
267 }
268 sMaxPipesPerMixer = min(value, maxSupported);
269}
270
Saurabh Shah59562ff2014-09-30 16:13:12 -0700271void MDPComp::setIdleTimeout(const uint32_t& timeout) {
272 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
273
274 if(sIdleInvalidator) {
275 if(timeout <= ONE_REFRESH_PERIOD_MS) {
276 //If the specified timeout is < 1 draw cycle worth, "virtually"
277 //disable idle timeout. The ideal way for clients to disable
278 //timeout is to set it to 0
279 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
280 ALOGI("Disabled idle timeout");
281 return;
282 }
283 sIdleInvalidator->setIdleTimeout(timeout);
284 ALOGI("Idle timeout set to %u", timeout);
285 } else {
286 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
287 }
288}
289
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800290void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800291 hwc_display_contents_1_t* list) {
292 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800293
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800294 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800295 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 if(!mCurrentFrame.isFBComposed[index]) {
297 layerProp[index].mFlags |= HWC_MDPCOMP;
298 layer->compositionType = HWC_OVERLAY;
299 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700301 /* Drop the layer when its already present in FB OR when it lies
302 * outside frame's ROI */
303 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800304 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700305 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800306 }
307 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700308}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500309
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800310void MDPComp::setRedraw(hwc_context_t *ctx,
311 hwc_display_contents_1_t* list) {
312 mCurrentFrame.needsRedraw = false;
313 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
314 (list->flags & HWC_GEOMETRY_CHANGED) ||
315 isSkipPresent(ctx, mDpy)) {
316 mCurrentFrame.needsRedraw = true;
317 }
318}
319
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800320MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700321 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700322 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800323}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800324
Saurabh Shahaa236822013-04-24 18:07:26 -0700325void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700326 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800327 if(mdpToLayer[i].pipeInfo) {
328 delete mdpToLayer[i].pipeInfo;
329 mdpToLayer[i].pipeInfo = NULL;
330 //We dont own the rotator
331 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800332 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800333 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800334
335 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
336 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700337 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800338
Saurabh Shahaa236822013-04-24 18:07:26 -0700339 layerCount = numLayers;
340 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800341 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700342 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800343 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800344}
345
Saurabh Shahaa236822013-04-24 18:07:26 -0700346void MDPComp::FrameInfo::map() {
347 // populate layer and MDP maps
348 int mdpIdx = 0;
349 for(int idx = 0; idx < layerCount; idx++) {
350 if(!isFBComposed[idx]) {
351 mdpToLayer[mdpIdx].listIndex = idx;
352 layerToMDP[idx] = mdpIdx++;
353 }
354 }
355}
356
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357MDPComp::LayerCache::LayerCache() {
358 reset();
359}
360
361void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700362 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530363 memset(&isFBComposed, true, sizeof(isFBComposed));
364 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800365 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700366}
367
368void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530369 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700370 for(int i = 0; i < numAppLayers; i++) {
371 hnd[i] = list->hwLayers[i].handle;
372 }
373}
374
375void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700376 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530377 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
378 memcpy(&drop, &curFrame.drop, sizeof(drop));
379}
380
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800381bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
382 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530383 if(layerCount != curFrame.layerCount)
384 return false;
385 for(int i = 0; i < curFrame.layerCount; i++) {
386 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
387 (curFrame.drop[i] != drop[i])) {
388 return false;
389 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800390 if(curFrame.isFBComposed[i] &&
391 (hnd[i] != list->hwLayers[i].handle)){
392 return false;
393 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530394 }
395 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800396}
397
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530398bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
399 hwc_display_contents_1_t* list) {
400
401 if(layerCount != ctx->listStats[dpy].numAppLayers)
402 return false;
403
404 if((list->flags & HWC_GEOMETRY_CHANGED) ||
405 isSkipPresent(ctx, dpy)) {
406 return false;
407 }
408
409 for(int i = 0; i < layerCount; i++) {
410 if(hnd[i] != list->hwLayers[i].handle)
411 return false;
412 }
413
414 return true;
415}
416
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700417bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
418 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800419 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530420 (not isValidDimension(ctx,layer)) ||
421 isSkipLayer(layer)) {
422 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700423 return false;
424 }
425 return true;
426}
427
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530428bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800429 private_handle_t *hnd = (private_handle_t *)layer->handle;
430
431 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700432 if (layer->flags & HWC_COLOR_FILL) {
433 // Color layer
434 return true;
435 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700436 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800437 return false;
438 }
439
Naseer Ahmede850a802013-09-06 13:12:52 -0400440 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400441 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400442 return false;
443
Saurabh Shah62e1d732013-09-17 10:44:05 -0700444 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700445 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700446 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700447 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
448 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700449 int dst_w = dst.right - dst.left;
450 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800451 float w_scale = ((float)crop_w / (float)dst_w);
452 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530453 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700454
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800455 /* Workaround for MDP HW limitation in DSI command mode panels where
456 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
457 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530458 * There also is a HW limilation in MDP, minimum block size is 2x2
459 * Fallback to GPU if height is less than 2.
460 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700461 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800462 return false;
463
Ramkumar Radhakrishnan1a763e92015-03-19 16:46:46 -0700464 /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
465 * those cases
466 */
467 if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
468 return false;
469 }
470
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800471 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530472 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800473 const float w_dscale = w_scale;
474 const float h_dscale = h_scale;
475
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800476 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700477
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530478 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700479 /* On targets that doesnt support Decimation (eg.,8x26)
480 * maximum downscale support is overlay pipe downscale.
481 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800482 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530483 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700484 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800485 return false;
486 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700487 // Decimation on macrotile format layers is not supported.
488 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530489 /* Bail out if
490 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700491 * 2. exceeds maximum downscale limit
492 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800493 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530494 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700495 w_dscale > maxMDPDownscale ||
496 h_dscale > maxMDPDownscale) {
497 return false;
498 }
499 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800500 return false;
501 }
502 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700503 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700504 return false;
505 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700506 }
507
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800508 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530509 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800510 const float w_uscale = 1.0f / w_scale;
511 const float h_uscale = 1.0f / h_scale;
512
513 if(w_uscale > upscale || h_uscale > upscale)
514 return false;
515 }
516
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800517 return true;
518}
519
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800520bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700521 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800522
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800523 if(!isEnabled()) {
524 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700525 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530526 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530527 qdutils::MDPVersion::getInstance().is8x16() ||
528 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800529 ctx->mVideoTransFlag &&
530 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700531 //1 Padding round to shift pipes across mixers
532 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
533 __FUNCTION__);
534 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700535 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
536 /* TODO: freeing up all the resources only for the targets having total
537 number of pipes < 8. Need to analyze number of VIG pipes used
538 for primary in previous draw cycle and accordingly decide
539 whether to fall back to full GPU comp or video only comp
540 */
541 if(isSecondaryConfiguring(ctx)) {
542 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
543 __FUNCTION__);
544 ret = false;
545 } else if(ctx->isPaddingRound) {
546 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
547 __FUNCTION__,mDpy);
548 ret = false;
549 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800550 } else if (ctx->isDMAStateChanging) {
551 // Bail out if a padding round has been invoked in order to switch DMA
552 // state to block mode. We need this to cater for the case when a layer
553 // requires rotation in the current frame.
554 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
555 __FUNCTION__);
556 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700557 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800558
Saurabh Shahaa236822013-04-24 18:07:26 -0700559 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800560}
561
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800562void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
563 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800564 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800565 dst = getIntersection(dst, roi);
566 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800567}
568
569/* 1) Identify layers that are not visible or lying outside the updating ROI and
570 * drop them from composition.
571 * 2) If we have a scaling layer which needs cropping against generated
572 * ROI, reset ROI to full resolution. */
573bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
574 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700575 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800576 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800577
578 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800579 if(!isValidRect(visibleRect)) {
580 mCurrentFrame.drop[i] = true;
581 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800582 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800583 }
584
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700585 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700586 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800587 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700588
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700589 if(!isValidRect(res)) {
590 mCurrentFrame.drop[i] = true;
591 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800592 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700593 /* Reset frame ROI when any layer which needs scaling also needs ROI
594 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800595 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800596 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700597 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
598 mCurrentFrame.dropCount = 0;
599 return false;
600 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800601
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800602 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530603 if (layer->blending == HWC_BLENDING_NONE &&
604 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800605 visibleRect = deductRect(visibleRect, res);
606 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700607 }
608 return true;
609}
610
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800611/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
612 * are updating. If DirtyRegion is applicable, calculate it by accounting all
613 * the changing layer's dirtyRegion. */
614void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
615 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700616 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800617 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700618 return;
619
620 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800621 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
622 (int)ctx->dpyAttr[mDpy].yres};
623
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700624 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800625 hwc_layer_1_t* layer = &list->hwLayers[index];
626 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800627 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700628 hwc_rect_t dst = layer->displayFrame;
629 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800630
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800631#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530632 if(!needsScaling(layer) && !layer->transform &&
633 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700634 {
635 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
636 int x_off = dst.left - src.left;
637 int y_off = dst.top - src.top;
638 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
639 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800640#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800641
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800642 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700643 }
644 }
645
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800646 /* No layer is updating. Still SF wants a refresh.*/
647 if(!isValidRect(roi))
648 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800649
650 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800651 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800652
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800653 ctx->listStats[mDpy].lRoi = roi;
654 if(!validateAndApplyROI(ctx, list))
655 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700656
657 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800658 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
659 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
660}
661
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800662void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
663 hwc_rect &dst) {
664 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
665 ctx->listStats[mDpy].rRoi);
666 hwc_rect tmpDst = getIntersection(dst, roi);
667 if(!isSameRect(dst, tmpDst)) {
668 crop.left = crop.left + (tmpDst.left - dst.left);
669 crop.top = crop.top + (tmpDst.top - dst.top);
670 crop.right = crop.left + (tmpDst.right - tmpDst.left);
671 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
672 dst = tmpDst;
673 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800674}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800675
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800676/* 1) Identify layers that are not visible or lying outside BOTH the updating
677 * ROI's and drop them from composition. If a layer is spanning across both
678 * the halves of the screen but needed by only ROI, the non-contributing
679 * half will not be programmed for MDP.
680 * 2) If we have a scaling layer which needs cropping against generated
681 * ROI, reset ROI to full resolution. */
682bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
683 hwc_display_contents_1_t* list) {
684
685 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
686
687 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
688 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
689
690 for(int i = numAppLayers - 1; i >= 0; i--){
691 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
692 {
693 mCurrentFrame.drop[i] = true;
694 mCurrentFrame.dropCount++;
695 continue;
696 }
697
698 const hwc_layer_1_t* layer = &list->hwLayers[i];
699 hwc_rect_t dstRect = layer->displayFrame;
700
701 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
702 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
703 hwc_rect_t res = getUnion(l_res, r_res);
704
705 if(!isValidRect(l_res) && !isValidRect(r_res)) {
706 mCurrentFrame.drop[i] = true;
707 mCurrentFrame.dropCount++;
708 } else {
709 /* Reset frame ROI when any layer which needs scaling also needs ROI
710 * cropping */
711 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
712 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
713 mCurrentFrame.dropCount = 0;
714 return false;
715 }
716
radhakrishna4efbdd62014-11-03 13:19:27 +0530717 if (layer->blending == HWC_BLENDING_NONE &&
718 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800719 visibleRectL = deductRect(visibleRectL, l_res);
720 visibleRectR = deductRect(visibleRectR, r_res);
721 }
722 }
723 }
724 return true;
725}
726/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
727 * are updating. If DirtyRegion is applicable, calculate it by accounting all
728 * the changing layer's dirtyRegion. */
729void MDPCompSplit::generateROI(hwc_context_t *ctx,
730 hwc_display_contents_1_t* list) {
731 if(!canPartialUpdate(ctx, list))
732 return;
733
734 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
735 int lSplit = getLeftSplit(ctx, mDpy);
736
737 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
738 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
739
740 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
741 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
742
743 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
744 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
745
746 for(int index = 0; index < numAppLayers; index++ ) {
747 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800748 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800749 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800750 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700751 hwc_rect_t dst = layer->displayFrame;
752 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800753
754#ifdef QCOM_BSP
755 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700756 {
757 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
758 int x_off = dst.left - src.left;
759 int y_off = dst.top - src.top;
760 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
761 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800762#endif
763
764 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
765 if(isValidRect(l_dst))
766 l_roi = getUnion(l_roi, l_dst);
767
768 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
769 if(isValidRect(r_dst))
770 r_roi = getUnion(r_roi, r_dst);
771 }
772 }
773
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700774 /* For panels that cannot accept commands in both the interfaces, we cannot
775 * send two ROI's (for each half). We merge them into single ROI and split
776 * them across lSplit for MDP mixer use. The ROI's will be merged again
777 * finally before udpating the panel in the driver. */
778 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
779 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
780 l_roi = getIntersection(temp_roi, l_frame);
781 r_roi = getIntersection(temp_roi, r_frame);
782 }
783
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800784 /* No layer is updating. Still SF wants a refresh. */
785 if(!isValidRect(l_roi) && !isValidRect(r_roi))
786 return;
787
788 l_roi = getSanitizeROI(l_roi, l_frame);
789 r_roi = getSanitizeROI(r_roi, r_frame);
790
791 ctx->listStats[mDpy].lRoi = l_roi;
792 ctx->listStats[mDpy].rRoi = r_roi;
793
794 if(!validateAndApplyROI(ctx, list))
795 resetROI(ctx, mDpy);
796
797 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
798 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
799 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
800 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
801 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
802 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700803}
804
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800805/* Checks for conditions where all the layers marked for MDP comp cannot be
806 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800807bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800808 hwc_display_contents_1_t* list){
809
Saurabh Shahaa236822013-04-24 18:07:26 -0700810 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800811
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700812 // Fall back to video only composition, if AIV video mode is enabled
813 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700814 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
815 __FUNCTION__, mDpy);
816 return false;
817 }
818
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530819 /* No Idle fall back if secure display or secure RGB layers are present
820 * or if there is only a single layer being composed */
821 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
822 !ctx->listStats[mDpy].secureRGBCount &&
823 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700824 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
825 return false;
826 }
827
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700828 // if secondary is configuring or Padding round, fall back to video only
829 // composition and release all assigned non VIG pipes from primary.
830 if(isSecondaryConfiguring(ctx)) {
831 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
832 __FUNCTION__);
833 return false;
834 } else if(ctx->isPaddingRound) {
835 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
836 __FUNCTION__,mDpy);
837 return false;
838 }
839
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500840 // No MDP composition for 3D
841 if(needs3DComposition(ctx, mDpy))
842 return false;
843
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700844 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800845 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700846 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800847 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
848 return false;
849 }
850
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800851 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800852 hwc_layer_1_t* layer = &list->hwLayers[i];
853 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800854
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800855 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700856 if(!canUseRotator(ctx, mDpy)) {
857 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
858 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700859 return false;
860 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800861 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530862
863 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
864 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800865 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700866 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530867 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
868 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
869 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800870 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700871
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700872 if(ctx->mAD->isDoable()) {
873 return false;
874 }
875
Saurabh Shahaa236822013-04-24 18:07:26 -0700876 //If all above hard conditions are met we can do full or partial MDP comp.
877 bool ret = false;
878 if(fullMDPComp(ctx, list)) {
879 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700880 } else if(fullMDPCompWithPTOR(ctx, list)) {
881 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700882 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700883 ret = true;
884 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530885
Saurabh Shahaa236822013-04-24 18:07:26 -0700886 return ret;
887}
888
889bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700890
891 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
892 return false;
893
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700894 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
895 for(int i = 0; i < numAppLayers; i++) {
896 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700897 if(not mCurrentFrame.drop[i] and
898 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700899 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
900 return false;
901 }
902 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800903
Saurabh Shahaa236822013-04-24 18:07:26 -0700904 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700905 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
906 sizeof(mCurrentFrame.isFBComposed));
907 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
908 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700909
Raj Kamal389d6e32014-08-04 14:43:24 +0530910 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800911 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530912 }
913
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800914 if(!postHeuristicsHandling(ctx, list)) {
915 ALOGD_IF(isDebug(), "post heuristic handling failed");
916 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700917 return false;
918 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700919 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
920 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700921 return true;
922}
923
Sushil Chauhandefd3522014-05-13 18:17:12 -0700924/* Full MDP Composition with Peripheral Tiny Overlap Removal.
925 * MDP bandwidth limitations can be avoided, if the overlap region
926 * covered by the smallest layer at a higher z-order, gets composed
927 * by Copybit on a render buffer, which can be queued to MDP.
928 */
929bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
930 hwc_display_contents_1_t* list) {
931
932 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
933 const int stagesForMDP = min(sMaxPipesPerMixer,
934 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
935
936 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700937 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700938 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
939 return false;
940 }
941
942 // Frame level checks
943 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
944 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
945 isSecurePresent(ctx, mDpy)) {
946 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
947 return false;
948 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700949 // MDP comp checks
950 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700951 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700952 if(not isSupportedForMDPComp(ctx, layer)) {
953 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
954 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700955 }
956 }
957
Sushil Chauhandefd3522014-05-13 18:17:12 -0700958 /* We cannot use this composition mode, if:
959 1. A below layer needs scaling.
960 2. Overlap is not peripheral to display.
961 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700962 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700963 */
964
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700965 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
966 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
967 memset(overlapRect, 0, sizeof(overlapRect));
968 int layerPixelCount, minPixelCount = 0;
969 int numPTORLayersFound = 0;
970 for (int i = numAppLayers-1; (i >= 0 &&
971 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700972 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700973 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700974 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700975 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
976 // PTOR layer should be peripheral and cannot have transform
977 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
978 has90Transform(layer)) {
979 continue;
980 }
981 if((3 * (layerPixelCount + minPixelCount)) >
982 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
983 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
984 continue;
985 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700986 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700987 for (int j = i-1; j >= 0; j--) {
988 // Check if the layers below this layer qualifies for PTOR comp
989 hwc_layer_1_t* layer = &list->hwLayers[j];
990 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700991 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700992 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700993 if (isValidRect(getIntersection(dispFrame, disFrame))) {
994 if (has90Transform(layer) || needsScaling(layer)) {
995 found = false;
996 break;
997 }
998 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700999 }
1000 }
1001 // Store the minLayer Index
1002 if(found) {
1003 minLayerIndex[numPTORLayersFound] = i;
1004 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1005 minPixelCount += layerPixelCount;
1006 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001007 }
1008 }
1009
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001010 // No overlap layers
1011 if (!numPTORLayersFound)
1012 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001013
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001014 // Store the displayFrame and the sourceCrops of the layers
1015 hwc_rect_t displayFrame[numAppLayers];
1016 hwc_rect_t sourceCrop[numAppLayers];
1017 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001018 hwc_layer_1_t* layer = &list->hwLayers[i];
1019 displayFrame[i] = layer->displayFrame;
1020 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001021 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001022
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301023 /**
1024 * It's possible that 2 PTOR layers might have overlapping.
1025 * In such case, remove the intersection(again if peripheral)
1026 * from the lower PTOR layer to avoid overlapping.
1027 * If intersection is not on peripheral then compromise
1028 * by reducing number of PTOR layers.
1029 **/
1030 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1031 if(isValidRect(commonRect)) {
1032 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1033 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1034 }
1035
1036 ctx->mPtorInfo.count = numPTORLayersFound;
1037 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1038 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1039 }
1040
1041 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1042 // reset PTOR
1043 ctx->mPtorInfo.count = 0;
1044 if(isValidRect(commonRect)) {
1045 // If PTORs are intersecting restore displayframe of PTOR[1]
1046 // before returning, as we have modified it above.
1047 list->hwLayers[minLayerIndex[1]].displayFrame =
1048 displayFrame[minLayerIndex[1]];
1049 }
1050 return false;
1051 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001052 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1053 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1054
Xu Yangcda012c2014-07-30 21:57:21 +08001055 // Store the blending mode, planeAlpha, and transform of PTOR layers
1056 int32_t blending[numPTORLayersFound];
1057 uint8_t planeAlpha[numPTORLayersFound];
1058 uint32_t transform[numPTORLayersFound];
1059
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001060 for(int j = 0; j < numPTORLayersFound; j++) {
1061 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001062
1063 // Update src crop of PTOR layer
1064 hwc_layer_1_t* layer = &list->hwLayers[index];
1065 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1066 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1067 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1068 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1069
1070 // Store & update w, h, format of PTOR layer
1071 private_handle_t *hnd = (private_handle_t *)layer->handle;
1072 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1073 layerWhf[j] = whf;
1074 hnd->width = renderBuf->width;
1075 hnd->height = renderBuf->height;
1076 hnd->format = renderBuf->format;
1077
Xu Yangcda012c2014-07-30 21:57:21 +08001078 // Store & update blending mode, planeAlpha and transform of PTOR layer
1079 blending[j] = layer->blending;
1080 planeAlpha[j] = layer->planeAlpha;
1081 transform[j] = layer->transform;
1082 layer->blending = HWC_BLENDING_NONE;
1083 layer->planeAlpha = 0xFF;
1084 layer->transform = 0;
1085
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001086 // Remove overlap from crop & displayFrame of below layers
1087 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001088 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001089 if(!isValidRect(getIntersection(layer->displayFrame,
1090 overlapRect[j]))) {
1091 continue;
1092 }
1093 // Update layer attributes
1094 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1095 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301096 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001097 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1098 layer->transform);
1099 layer->sourceCropf.left = (float)srcCrop.left;
1100 layer->sourceCropf.top = (float)srcCrop.top;
1101 layer->sourceCropf.right = (float)srcCrop.right;
1102 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1103 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001104 }
1105
1106 mCurrentFrame.mdpCount = numAppLayers;
1107 mCurrentFrame.fbCount = 0;
1108 mCurrentFrame.fbZ = -1;
1109
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301110 for (int j = 0; j < numAppLayers; j++) {
1111 if(isValidRect(list->hwLayers[j].displayFrame)) {
1112 mCurrentFrame.isFBComposed[j] = false;
1113 } else {
1114 mCurrentFrame.mdpCount--;
1115 mCurrentFrame.drop[j] = true;
1116 }
1117 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001118
1119 bool result = postHeuristicsHandling(ctx, list);
1120
1121 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001122 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001123 hwc_layer_1_t* layer = &list->hwLayers[i];
1124 layer->displayFrame = displayFrame[i];
1125 layer->sourceCropf.left = (float)sourceCrop[i].left;
1126 layer->sourceCropf.top = (float)sourceCrop[i].top;
1127 layer->sourceCropf.right = (float)sourceCrop[i].right;
1128 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1129 }
1130
Xu Yangcda012c2014-07-30 21:57:21 +08001131 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001132 for (int i = 0; i < numPTORLayersFound; i++) {
1133 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001134 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001135 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1136 hnd->width = layerWhf[i].w;
1137 hnd->height = layerWhf[i].h;
1138 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001139 layer->blending = blending[i];
1140 layer->planeAlpha = planeAlpha[i];
1141 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001142 }
1143
Sushil Chauhandefd3522014-05-13 18:17:12 -07001144 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001145 // reset PTOR
1146 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001147 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001148 } else {
1149 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1150 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001151 }
1152
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001153 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1154 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001155 return result;
1156}
1157
Saurabh Shahaa236822013-04-24 18:07:26 -07001158bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1159{
radhakrishnac3198ff2015-03-10 17:10:02 +05301160 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1161 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001162 return false;
1163 }
1164
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001165 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301166 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1167 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001168 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001169 cacheBasedComp(ctx, list);
1170 } else {
1171 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001172 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001173 }
1174
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001175 return ret;
1176}
1177
1178bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1179 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001180 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1181 return false;
1182
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001183 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001184 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001185 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001186
1187 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1188 for(int i = 0; i < numAppLayers; i++) {
1189 if(!mCurrentFrame.isFBComposed[i]) {
1190 hwc_layer_1_t* layer = &list->hwLayers[i];
1191 if(not isSupportedForMDPComp(ctx, layer)) {
1192 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1193 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001194 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001195 return false;
1196 }
1197 }
1198 }
1199
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001200 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001201 /* mark secure RGB layers for MDP comp */
1202 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301203 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001204 if(!ret) {
1205 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001206 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001207 return false;
1208 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001209
1210 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001211
Raj Kamal389d6e32014-08-04 14:43:24 +05301212 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001213 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301214 }
1215
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001216 if(!postHeuristicsHandling(ctx, list)) {
1217 ALOGD_IF(isDebug(), "post heuristic handling failed");
1218 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001219 return false;
1220 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001221 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1222 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001223
Saurabh Shahaa236822013-04-24 18:07:26 -07001224 return true;
1225}
1226
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001227bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001228 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001229 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1230 return false;
1231
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001232 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001233 return false;
1234 }
1235
Saurabh Shahb772ae32013-11-18 15:40:02 -08001236 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001237 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1238 const int stagesForMDP = min(sMaxPipesPerMixer,
1239 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001240
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001241 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1242 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1243 int lastMDPSupportedIndex = numAppLayers;
1244 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001245
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001246 //Find the minimum MDP batch size
1247 for(int i = 0; i < numAppLayers;i++) {
1248 if(mCurrentFrame.drop[i]) {
1249 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001250 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001251 }
1252 hwc_layer_1_t* layer = &list->hwLayers[i];
1253 if(not isSupportedForMDPComp(ctx, layer)) {
1254 lastMDPSupportedIndex = i;
1255 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1256 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001257 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001258 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001259 }
1260
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001261 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1262 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1263 mCurrentFrame.dropCount);
1264
1265 //Start at a point where the fb batch should at least have 2 layers, for
1266 //this mode to be justified.
1267 while(fbBatchSize < 2) {
1268 ++fbBatchSize;
1269 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001270 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001271
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001272 //If there are no layers for MDP, this mode doesnt make sense.
1273 if(mdpBatchSize < 1) {
1274 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1275 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001276 return false;
1277 }
1278
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001279 mCurrentFrame.reset(numAppLayers);
1280
1281 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1282 while(mdpBatchSize > 0) {
1283 //Mark layers for MDP comp
1284 int mdpBatchLeft = mdpBatchSize;
1285 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1286 if(mCurrentFrame.drop[i]) {
1287 continue;
1288 }
1289 mCurrentFrame.isFBComposed[i] = false;
1290 --mdpBatchLeft;
1291 }
1292
1293 mCurrentFrame.fbZ = mdpBatchSize;
1294 mCurrentFrame.fbCount = fbBatchSize;
1295 mCurrentFrame.mdpCount = mdpBatchSize;
1296
1297 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1298 __FUNCTION__, mdpBatchSize, fbBatchSize,
1299 mCurrentFrame.dropCount);
1300
1301 if(postHeuristicsHandling(ctx, list)) {
1302 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001303 __FUNCTION__);
1304 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1305 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001306 return true;
1307 }
1308
1309 reset(ctx);
1310 --mdpBatchSize;
1311 ++fbBatchSize;
1312 }
1313
1314 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001315}
1316
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001317bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301318 if(mDpy or isSecurePresent(ctx, mDpy) or
1319 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001320 return false;
1321 }
1322 return true;
1323}
1324
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001325bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1326 hwc_display_contents_1_t* list){
1327 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1328 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001329 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001330 return false;
1331 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001332 if(ctx->listStats[mDpy].secureUI)
1333 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001334 return true;
1335}
1336
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001337bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1338 hwc_display_contents_1_t* list) {
1339 const bool secureOnly = true;
1340 return videoOnlyComp(ctx, list, not secureOnly) or
1341 videoOnlyComp(ctx, list, secureOnly);
1342}
1343
1344bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001345 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001346 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1347 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301348
Saurabh Shahaa236822013-04-24 18:07:26 -07001349 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301350 if(!isSecurePresent(ctx, mDpy)) {
1351 /* Bail out if we are processing only secured video layers
1352 * and we dont have any */
1353 if(secureOnly) {
1354 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1355 return false;
1356 }
1357 /* No Idle fall back for secure video layers and if there is only
1358 * single layer being composed. */
1359 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1360 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1361 return false;
1362 }
1363 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001364
Saurabh Shahaa236822013-04-24 18:07:26 -07001365 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001366 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001367 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001368 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001369
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001370 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1371 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001372 return false;
1373 }
1374
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001375 if(mCurrentFrame.fbCount)
1376 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001377
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001378 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001379 adjustForSourceSplit(ctx, list);
1380 }
1381
1382 if(!postHeuristicsHandling(ctx, list)) {
1383 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301384 if(errno == ENOBUFS) {
1385 ALOGD_IF(isDebug(), "SMP Allocation failed");
1386 //On SMP allocation failure in video only comp add padding round
1387 ctx->isPaddingRound = true;
1388 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001389 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001390 return false;
1391 }
1392
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001393 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1394 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001395 return true;
1396}
1397
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001398/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1399bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1400 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001401 // Fall back to video only composition, if AIV video mode is enabled
1402 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001403 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1404 __FUNCTION__, mDpy);
1405 return false;
1406 }
1407
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001408 // No MDP composition for 3D
1409 if(needs3DComposition(ctx,mDpy))
1410 return false;
1411
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001412 const bool secureOnly = true;
1413 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1414 mdpOnlyLayersComp(ctx, list, secureOnly);
1415
1416}
1417
1418bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1419 hwc_display_contents_1_t* list, bool secureOnly) {
1420
1421 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1422 return false;
1423
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301424 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1425 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1426 /* Bail out if we are processing only secured video/ui layers
1427 * and we dont have any */
1428 if(secureOnly) {
1429 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1430 return false;
1431 }
1432 /* No Idle fall back for secure video/ui layers and if there is only
1433 * single layer being composed. */
1434 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1435 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1436 return false;
1437 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001438 }
1439
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001440 /* Bail out if we dont have any secure RGB layers */
1441 if (!ctx->listStats[mDpy].secureRGBCount) {
1442 reset(ctx);
1443 return false;
1444 }
1445
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001446 mCurrentFrame.reset(numAppLayers);
1447 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1448
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001449 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001450 /* mark secure RGB layers for MDP comp */
1451 updateSecureRGB(ctx, list);
1452
1453 if(mCurrentFrame.mdpCount == 0) {
1454 reset(ctx);
1455 return false;
1456 }
1457
1458 /* find the maximum batch of layers to be marked for framebuffer */
1459 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1460 if(!ret) {
1461 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1462 reset(ctx);
1463 return false;
1464 }
1465
1466 if(sEnableYUVsplit){
1467 adjustForSourceSplit(ctx, list);
1468 }
1469
1470 if(!postHeuristicsHandling(ctx, list)) {
1471 ALOGD_IF(isDebug(), "post heuristic handling failed");
1472 reset(ctx);
1473 return false;
1474 }
1475
1476 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1477 __FUNCTION__);
1478 return true;
1479}
1480
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001481/* Checks for conditions where YUV layers cannot be bypassed */
1482bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001483 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001484 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001485 return false;
1486 }
1487
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001488 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001489 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1490 return false;
1491 }
1492
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001493 if(isSecuring(ctx, layer)) {
1494 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1495 return false;
1496 }
1497
Saurabh Shah4fdde762013-04-30 18:47:33 -07001498 if(!isValidDimension(ctx, layer)) {
1499 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1500 __FUNCTION__);
1501 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001502 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001503
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001504 if(layer->planeAlpha < 0xFF) {
1505 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1506 in video only mode",
1507 __FUNCTION__);
1508 return false;
1509 }
1510
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001511 return true;
1512}
1513
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001514/* Checks for conditions where Secure RGB layers cannot be bypassed */
1515bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1516 if(isSkipLayer(layer)) {
1517 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1518 __FUNCTION__, mDpy);
1519 return false;
1520 }
1521
1522 if(isSecuring(ctx, layer)) {
1523 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1524 return false;
1525 }
1526
1527 if(not isSupportedForMDPComp(ctx, layer)) {
1528 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1529 __FUNCTION__);
1530 return false;
1531 }
1532 return true;
1533}
1534
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301535/* starts at fromIndex and check for each layer to find
1536 * if it it has overlapping with any Updating layer above it in zorder
1537 * till the end of the batch. returns true if it finds any intersection */
1538bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1539 int fromIndex, int toIndex) {
1540 for(int i = fromIndex; i < toIndex; i++) {
1541 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1542 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1543 return false;
1544 }
1545 }
1546 }
1547 return true;
1548}
1549
1550/* Checks if given layer at targetLayerIndex has any
1551 * intersection with all the updating layers in beween
1552 * fromIndex and toIndex. Returns true if it finds intersectiion */
1553bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1554 int fromIndex, int toIndex, int targetLayerIndex) {
1555 for(int i = fromIndex; i <= toIndex; i++) {
1556 if(!mCurrentFrame.isFBComposed[i]) {
1557 if(areLayersIntersecting(&list->hwLayers[i],
1558 &list->hwLayers[targetLayerIndex])) {
1559 return true;
1560 }
1561 }
1562 }
1563 return false;
1564}
1565
1566int MDPComp::getBatch(hwc_display_contents_1_t* list,
1567 int& maxBatchStart, int& maxBatchEnd,
1568 int& maxBatchCount) {
1569 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301570 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001571 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301572 while (i < mCurrentFrame.layerCount) {
1573 int batchCount = 0;
1574 int batchStart = i;
1575 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001576 /* Adjust batch Z order with the dropped layers so far */
1577 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301578 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301579 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580 while(i < mCurrentFrame.layerCount) {
1581 if(!mCurrentFrame.isFBComposed[i]) {
1582 if(!batchCount) {
1583 i++;
1584 break;
1585 }
1586 updatingLayersAbove++;
1587 i++;
1588 continue;
1589 } else {
1590 if(mCurrentFrame.drop[i]) {
1591 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001592 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301593 continue;
1594 } else if(updatingLayersAbove <= 0) {
1595 batchCount++;
1596 batchEnd = i;
1597 i++;
1598 continue;
1599 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1600
1601 // We have a valid updating layer already. If layer-i not
1602 // have overlapping with all updating layers in between
1603 // batch-start and i, then we can add layer i to batch.
1604 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1605 batchCount++;
1606 batchEnd = i;
1607 i++;
1608 continue;
1609 } else if(canPushBatchToTop(list, batchStart, i)) {
1610 //If All the non-updating layers with in this batch
1611 //does not have intersection with the updating layers
1612 //above in z-order, then we can safely move the batch to
1613 //higher z-order. Increment fbZ as it is moving up.
1614 if( firstZReverseIndex < 0) {
1615 firstZReverseIndex = i;
1616 }
1617 batchCount++;
1618 batchEnd = i;
1619 fbZ += updatingLayersAbove;
1620 i++;
1621 updatingLayersAbove = 0;
1622 continue;
1623 } else {
1624 //both failed.start the loop again from here.
1625 if(firstZReverseIndex >= 0) {
1626 i = firstZReverseIndex;
1627 }
1628 break;
1629 }
1630 }
1631 }
1632 }
1633 if(batchCount > maxBatchCount) {
1634 maxBatchCount = batchCount;
1635 maxBatchStart = batchStart;
1636 maxBatchEnd = batchEnd;
1637 fbZOrder = fbZ;
1638 }
1639 }
1640 return fbZOrder;
1641}
1642
1643bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1644 hwc_display_contents_1_t* list) {
1645 /* Idea is to keep as many non-updating(cached) layers in FB and
1646 * send rest of them through MDP. This is done in 2 steps.
1647 * 1. Find the maximum contiguous batch of non-updating layers.
1648 * 2. See if we can improve this batch size for caching by adding
1649 * opaque layers around the batch, if they don't have
1650 * any overlapping with the updating layers in between.
1651 * NEVER mark an updating layer for caching.
1652 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001653
1654 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001655 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301657 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001659 /* Nothing is cached. No batching needed */
1660 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001661 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001662 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001663
1664 /* No MDP comp layers, try to use other comp modes */
1665 if(mCurrentFrame.mdpCount == 0) {
1666 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001667 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001668
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301669 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001670
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301671 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001673 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001674 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301675 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001676 if(!mCurrentFrame.drop[i]){
1677 //If an unsupported layer is being attempted to
1678 //be pulled out we should fail
1679 if(not isSupportedForMDPComp(ctx, layer)) {
1680 return false;
1681 }
1682 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001683 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001684 }
1685 }
1686
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301687 // update the frame data
1688 mCurrentFrame.fbZ = fbZ;
1689 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001690 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001691 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001692
1693 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301694 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001695
1696 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001697}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001698
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001699void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001700 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001701 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001702 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001703
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001704 for(int i = 0; i < numAppLayers; i++) {
1705 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001706 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001707 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001708 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001709 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001710 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001711 }
1712 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001713
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001714 frame.fbCount = fbCount;
1715 frame.mdpCount = frame.layerCount - frame.fbCount
1716 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001717
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001718 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1719 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001720}
1721
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001722// drop other non-AIV layers from external display list.
1723void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001724 hwc_display_contents_1_t* list) {
1725 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1726 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001727 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001728 mCurrentFrame.dropCount++;
1729 mCurrentFrame.drop[i] = true;
1730 }
1731 }
1732 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1733 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1734 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1735 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1736 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1737 mCurrentFrame.dropCount);
1738}
1739
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001740void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001741 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001742 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1743 for(int index = 0;index < nYuvCount; index++){
1744 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1745 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1746
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001747 if(mCurrentFrame.drop[nYuvIndex]) {
1748 continue;
1749 }
1750
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001751 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001752 if(!frame.isFBComposed[nYuvIndex]) {
1753 frame.isFBComposed[nYuvIndex] = true;
1754 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001755 }
1756 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001757 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001758 private_handle_t *hnd = (private_handle_t *)layer->handle;
1759 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001760 frame.isFBComposed[nYuvIndex] = false;
1761 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001762 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001763 }
1764 }
1765 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001766
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001767 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1768 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001769}
1770
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001771void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1772 hwc_display_contents_1_t* list) {
1773 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1774 for(int index = 0;index < nSecureRGBCount; index++){
1775 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1776 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1777
1778 if(!isSecureRGBDoable(ctx, layer)) {
1779 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1780 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1781 mCurrentFrame.fbCount++;
1782 }
1783 } else {
1784 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1785 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1786 mCurrentFrame.fbCount--;
1787 }
1788 }
1789 }
1790
1791 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1792 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1793 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1794 mCurrentFrame.fbCount);
1795}
1796
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001797hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1798 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001799 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001800
1801 /* Update only the region of FB needed for composition */
1802 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1803 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1804 hwc_layer_1_t* layer = &list->hwLayers[i];
1805 hwc_rect_t dst = layer->displayFrame;
1806 fbRect = getUnion(fbRect, dst);
1807 }
1808 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001809 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001810 return fbRect;
1811}
1812
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001813bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1814 hwc_display_contents_1_t* list) {
1815
1816 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001817 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001818 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1819 return false;
1820 }
1821
1822 //Limitations checks
1823 if(!hwLimitationsCheck(ctx, list)) {
1824 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1825 return false;
1826 }
1827
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001828 //Configure framebuffer first if applicable
1829 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001830 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001831 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1832 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001833 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1834 __FUNCTION__);
1835 return false;
1836 }
1837 }
1838
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001839 mCurrentFrame.map();
1840
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001841 if(!allocLayerPipes(ctx, list)) {
1842 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001843 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001844 }
1845
1846 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001847 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001848 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001849 int mdpIndex = mCurrentFrame.layerToMDP[index];
1850 hwc_layer_1_t* layer = &list->hwLayers[index];
1851
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301852 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1853 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1854 mdpNextZOrder++;
1855 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001856 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1857 cur_pipe->zOrder = mdpNextZOrder++;
1858
radhakrishnac9a67412013-09-25 17:40:42 +05301859 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301860 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301861 if(configure4k2kYuv(ctx, layer,
1862 mCurrentFrame.mdpToLayer[mdpIndex])
1863 != 0 ){
1864 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1865 for layer %d",__FUNCTION__, index);
1866 return false;
1867 }
1868 else{
1869 mdpNextZOrder++;
1870 }
1871 continue;
1872 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001873 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1874 mdpNextZOrder++;
1875 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001876 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1877 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301878 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001879 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001880 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001881 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001882 }
1883
Saurabh Shaha36be922013-12-16 18:18:39 -08001884 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1885 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1886 ,__FUNCTION__, mDpy);
1887 return false;
1888 }
1889
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001890 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001891 return true;
1892}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001893
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001894bool MDPComp::resourceCheck(hwc_context_t* ctx,
1895 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001896 const bool fbUsed = mCurrentFrame.fbCount;
1897 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1898 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1899 return false;
1900 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001901
1902 //Will benefit cases where a video has non-updating background.
1903 if((mDpy > HWC_DISPLAY_PRIMARY) and
1904 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1905 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1906 return false;
1907 }
1908
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001909 // Init rotCount to number of rotate sessions used by other displays
1910 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1911 // Count the number of rotator sessions required for current display
1912 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1913 if(!mCurrentFrame.isFBComposed[index]) {
1914 hwc_layer_1_t* layer = &list->hwLayers[index];
1915 private_handle_t *hnd = (private_handle_t *)layer->handle;
1916 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1917 rotCount++;
1918 }
1919 }
1920 }
1921 // if number of layers to rotate exceeds max rotator sessions, bail out.
1922 if(rotCount > RotMgr::MAX_ROT_SESS) {
1923 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1924 __FUNCTION__, mDpy);
1925 return false;
1926 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001927 return true;
1928}
1929
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301930bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1931 hwc_display_contents_1_t* list) {
1932
1933 //A-family hw limitation:
1934 //If a layer need alpha scaling, MDP can not support.
1935 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1936 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1937 if(!mCurrentFrame.isFBComposed[i] &&
1938 isAlphaScaled( &list->hwLayers[i])) {
1939 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1940 return false;
1941 }
1942 }
1943 }
1944
1945 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1946 //If multiple layers requires downscaling and also they are overlapping
1947 //fall back to GPU since MDSS can not handle it.
1948 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1949 qdutils::MDPVersion::getInstance().is8x26()) {
1950 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1951 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1952 if(!mCurrentFrame.isFBComposed[i] &&
1953 isDownscaleRequired(botLayer)) {
1954 //if layer-i is marked for MDP and needs downscaling
1955 //check if any MDP layer on top of i & overlaps with layer-i
1956 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1957 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1958 if(!mCurrentFrame.isFBComposed[j] &&
1959 isDownscaleRequired(topLayer)) {
1960 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1961 topLayer->displayFrame);
1962 if(isValidRect(r))
1963 return false;
1964 }
1965 }
1966 }
1967 }
1968 }
1969 return true;
1970}
1971
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001972// Checks only if videos or single layer(RGB) is updating
1973// which is used for setting dynamic fps or perf hint for single
1974// layer video playback
1975bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1976 hwc_display_contents_1_t* list) {
1977 bool support = false;
1978 FrameInfo frame;
1979 frame.reset(mCurrentFrame.layerCount);
1980 memset(&frame.drop, 0, sizeof(frame.drop));
1981 frame.dropCount = 0;
1982 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1983 updateLayerCache(ctx, list, frame);
1984 updateYUV(ctx, list, false /*secure only*/, frame);
1985 // There are only updating YUV layers or there is single RGB
1986 // Layer(Youtube)
1987 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1988 (frame.layerCount == 1)) {
1989 support = true;
1990 }
1991 return support;
1992}
1993
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301994void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1995 //For primary display, set the dynamic refreshrate
1996 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1997 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301998 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1999 MDPVersion& mdpHw = MDPVersion::getInstance();
2000 if(sIdleFallBack) {
2001 //Set minimum panel refresh rate during idle timeout
2002 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002003 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302004 //Set the new fresh rate, if there is only one updating YUV layer
2005 //or there is one single RGB layer with this request
2006 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2007 }
2008 setRefreshRate(ctx, mDpy, refreshRate);
2009 }
2010}
2011
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002012int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002013 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002014 char property[PROPERTY_VALUE_MAX];
2015
Raj Kamal4393eaa2014-06-06 13:45:20 +05302016 if(!ctx || !list) {
2017 ALOGE("%s: Invalid context or list",__FUNCTION__);
2018 mCachedFrame.reset();
2019 return -1;
2020 }
2021
2022 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002023 if(mDpy == HWC_DISPLAY_PRIMARY) {
2024 sSimulationFlags = 0;
2025 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2026 int currentFlags = atoi(property);
2027 if(currentFlags != sSimulationFlags) {
2028 sSimulationFlags = currentFlags;
2029 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2030 sSimulationFlags, sSimulationFlags);
2031 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002032 }
2033 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002034 // reset PTOR
2035 if(!mDpy)
2036 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002037
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302038 //reset old data
2039 mCurrentFrame.reset(numLayers);
2040 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2041 mCurrentFrame.dropCount = 0;
2042
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302043 //Do not cache the information for next draw cycle.
2044 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2045 ALOGI("%s: Unsupported layer count for mdp composition",
2046 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002047 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302048#ifdef DYNAMIC_FPS
2049 setDynRefreshRate(ctx, list);
2050#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002051 return -1;
2052 }
2053
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002054 // Detect the start of animation and fall back to GPU only once to cache
2055 // all the layers in FB and display FB content untill animation completes.
2056 if(ctx->listStats[mDpy].isDisplayAnimating) {
2057 mCurrentFrame.needsRedraw = false;
2058 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2059 mCurrentFrame.needsRedraw = true;
2060 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2061 }
2062 setMDPCompLayerFlags(ctx, list);
2063 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302064#ifdef DYNAMIC_FPS
2065 setDynRefreshRate(ctx, list);
2066#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002067 ret = -1;
2068 return ret;
2069 } else {
2070 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2071 }
2072
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302073 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2074 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2075
2076 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2077 mCurrentFrame.needsRedraw = false;
2078 setMDPCompLayerFlags(ctx, list);
2079 mCachedFrame.updateCounts(mCurrentFrame);
2080#ifdef DYNAMIC_FPS
2081 setDynRefreshRate(ctx, list);
2082#endif
2083 return -1;
2084
2085 }
2086
Saurabh Shahb39f8152013-08-22 10:21:44 -07002087 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002088 if(isFrameDoable(ctx)) {
2089 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002090 // if AIV Video mode is enabled, drop all non AIV layers from the
2091 // external display list.
2092 if(ctx->listStats[mDpy].mAIVVideoMode) {
2093 dropNonAIVLayers(ctx, list);
2094 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002095
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002096 // if tryFullFrame fails, try to push all video and secure RGB layers
2097 // to MDP for composition.
2098 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002099 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302100 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002101 setMDPCompLayerFlags(ctx, list);
2102 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002103 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002104 reset(ctx);
2105 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2106 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002107 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002108 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2109 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002110 }
2111 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302112 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2113 enablePartialUpdateForMDP3) {
2114 generateROI(ctx, list);
2115 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2116 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2117 }
2118 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002119 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2120 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002121 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002122 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002123
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002124 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002125 ALOGD("GEOMETRY change: %d",
2126 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002127 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002128 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002129 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002130 }
2131
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002132#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302133 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002134#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002135 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002136
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002137 mCachedFrame.cacheAll(list);
2138 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002139 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002140}
2141
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002142bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302143
2144 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302145 int mdpIndex = mCurrentFrame.layerToMDP[index];
2146 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2147 info.pipeInfo = new MdpYUVPipeInfo;
2148 info.rot = NULL;
2149 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302150
2151 pipe_info.lIndex = ovutils::OV_INVALID;
2152 pipe_info.rIndex = ovutils::OV_INVALID;
2153
Saurabh Shahc62f3982014-03-05 14:28:26 -08002154 Overlay::PipeSpecs pipeSpecs;
2155 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2156 pipeSpecs.needsScaling = true;
2157 pipeSpecs.dpy = mDpy;
2158 pipeSpecs.fb = false;
2159
2160 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302161 if(pipe_info.lIndex == ovutils::OV_INVALID){
2162 bRet = false;
2163 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2164 __FUNCTION__);
2165 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002166 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302167 if(pipe_info.rIndex == ovutils::OV_INVALID){
2168 bRet = false;
2169 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2170 __FUNCTION__);
2171 }
2172 return bRet;
2173}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002174
2175int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2176 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002177 if (ctx->mPtorInfo.isActive()) {
2178 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002179 if (fd < 0) {
2180 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002181 }
2182 }
2183 return fd;
2184}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002185//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002186
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002187void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302188 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002189 //If 4k2k Yuv layer split is possible, and if
2190 //fbz is above 4k2k layer, increment fb zorder by 1
2191 //as we split 4k2k layer and increment zorder for right half
2192 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002193 if(!ctx)
2194 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002195 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302196 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2197 index++) {
2198 if(!mCurrentFrame.isFBComposed[index]) {
2199 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2200 mdpNextZOrder++;
2201 }
2202 mdpNextZOrder++;
2203 hwc_layer_1_t* layer = &list->hwLayers[index];
2204 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302205 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302206 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2207 mCurrentFrame.fbZ += 1;
2208 mdpNextZOrder++;
2209 //As we split 4kx2k yuv layer and program to 2 VG pipes
2210 //(if available) increase mdpcount by 1.
2211 mCurrentFrame.mdpCount++;
2212 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002213 }
2214 }
2215 }
radhakrishnac9a67412013-09-25 17:40:42 +05302216}
2217
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002218/*
2219 * Configures pipe(s) for MDP composition
2220 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002221int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002222 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002223 MdpPipeInfoNonSplit& mdp_info =
2224 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302225 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002226 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002227 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002228
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002229 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2230 __FUNCTION__, layer, zOrder, dest);
2231
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002232 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002233 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002234}
2235
Saurabh Shah88e4d272013-09-03 13:31:29 -07002236bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002237 hwc_display_contents_1_t* list) {
2238 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002239
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002240 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002241
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002242 hwc_layer_1_t* layer = &list->hwLayers[index];
2243 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302244 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002245 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302246 continue;
2247 }
2248 }
2249
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002250 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002251 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002252 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002253 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002254 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002255
Saurabh Shahc62f3982014-03-05 14:28:26 -08002256 Overlay::PipeSpecs pipeSpecs;
2257 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2258 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2259 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2260 (qdutils::MDPVersion::getInstance().is8x26() and
2261 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2262 pipeSpecs.dpy = mDpy;
2263 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002264 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002265
Saurabh Shahc62f3982014-03-05 14:28:26 -08002266 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2267
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002268 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002269 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002270 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002271 }
2272 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002273 return true;
2274}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002275
radhakrishnac9a67412013-09-25 17:40:42 +05302276int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2277 PipeLayerPair& PipeLayerPair) {
2278 MdpYUVPipeInfo& mdp_info =
2279 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2280 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302281 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302282 eDest lDest = mdp_info.lIndex;
2283 eDest rDest = mdp_info.rIndex;
2284
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002285 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302286 lDest, rDest, &PipeLayerPair.rot);
2287}
2288
Saurabh Shah88e4d272013-09-03 13:31:29 -07002289bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002290
Raj Kamal4393eaa2014-06-06 13:45:20 +05302291 if(!isEnabled() or !mModeOn) {
2292 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302293 return true;
2294 }
2295
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002296 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002297 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002298
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002299 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2300 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002301 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002302 if(mCurrentFrame.isFBComposed[i]) continue;
2303
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002304 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002305 private_handle_t *hnd = (private_handle_t *)layer->handle;
2306 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002307 if (!(layer->flags & HWC_COLOR_FILL)) {
2308 ALOGE("%s handle null", __FUNCTION__);
2309 return false;
2310 }
2311 // No PLAY for Color layer
2312 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2313 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002314 }
2315
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002316 int mdpIndex = mCurrentFrame.layerToMDP[i];
2317
Raj Kamal389d6e32014-08-04 14:43:24 +05302318 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302319 {
2320 MdpYUVPipeInfo& pipe_info =
2321 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2322 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2323 ovutils::eDest indexL = pipe_info.lIndex;
2324 ovutils::eDest indexR = pipe_info.rIndex;
2325 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302326 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302327 if(rot) {
2328 rot->queueBuffer(fd, offset);
2329 fd = rot->getDstMemId();
2330 offset = rot->getDstOffset();
2331 }
2332 if(indexL != ovutils::OV_INVALID) {
2333 ovutils::eDest destL = (ovutils::eDest)indexL;
2334 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2335 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2336 if (!ov.queueBuffer(fd, offset, destL)) {
2337 ALOGE("%s: queueBuffer failed for display:%d",
2338 __FUNCTION__, mDpy);
2339 return false;
2340 }
2341 }
2342
2343 if(indexR != ovutils::OV_INVALID) {
2344 ovutils::eDest destR = (ovutils::eDest)indexR;
2345 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2346 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2347 if (!ov.queueBuffer(fd, offset, destR)) {
2348 ALOGE("%s: queueBuffer failed for display:%d",
2349 __FUNCTION__, mDpy);
2350 return false;
2351 }
2352 }
2353 }
2354 else{
2355 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002356 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302357 ovutils::eDest dest = pipe_info.index;
2358 if(dest == ovutils::OV_INVALID) {
2359 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002360 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302361 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002362
radhakrishnac9a67412013-09-25 17:40:42 +05302363 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2364 continue;
2365 }
2366
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002367 int fd = hnd->fd;
2368 uint32_t offset = (uint32_t)hnd->offset;
2369 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2370 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002371 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002372 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002373 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002374 }
2375
radhakrishnac9a67412013-09-25 17:40:42 +05302376 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2377 using pipe: %d", __FUNCTION__, layer,
2378 hnd, dest );
2379
radhakrishnac9a67412013-09-25 17:40:42 +05302380 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2381 if(rot) {
2382 if(!rot->queueBuffer(fd, offset))
2383 return false;
2384 fd = rot->getDstMemId();
2385 offset = rot->getDstOffset();
2386 }
2387
2388 if (!ov.queueBuffer(fd, offset, dest)) {
2389 ALOGE("%s: queueBuffer failed for display:%d ",
2390 __FUNCTION__, mDpy);
2391 return false;
2392 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002393 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002394
2395 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002396 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002397 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002398}
2399
Saurabh Shah88e4d272013-09-03 13:31:29 -07002400//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002401
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002402void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302403 hwc_display_contents_1_t* list){
2404 //if 4kx2k yuv layer is totally present in either in left half
2405 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302406 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302407 if(mCurrentFrame.fbZ >= 0) {
2408 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2409 index++) {
2410 if(!mCurrentFrame.isFBComposed[index]) {
2411 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2412 mdpNextZOrder++;
2413 }
2414 mdpNextZOrder++;
2415 hwc_layer_1_t* layer = &list->hwLayers[index];
2416 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002417 if(isYUVSplitNeeded(hnd) ||
2418 (needs3DComposition(ctx,mDpy) &&
2419 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302420 hwc_rect_t dst = layer->displayFrame;
2421 if((dst.left > lSplit) || (dst.right < lSplit)) {
2422 mCurrentFrame.mdpCount += 1;
2423 }
2424 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2425 mCurrentFrame.fbZ += 1;
2426 mdpNextZOrder++;
2427 }
2428 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002429 }
radhakrishnac9a67412013-09-25 17:40:42 +05302430 }
2431}
2432
Saurabh Shah88e4d272013-09-03 13:31:29 -07002433bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002434 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002435
Saurabh Shahc62f3982014-03-05 14:28:26 -08002436 const int lSplit = getLeftSplit(ctx, mDpy);
2437 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002438 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002439 pipe_info.lIndex = ovutils::OV_INVALID;
2440 pipe_info.rIndex = ovutils::OV_INVALID;
2441
Saurabh Shahc62f3982014-03-05 14:28:26 -08002442 Overlay::PipeSpecs pipeSpecs;
2443 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2444 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2445 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2446 pipeSpecs.dpy = mDpy;
2447 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2448 pipeSpecs.fb = false;
2449
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002450 // Acquire pipe only for the updating half
2451 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2452 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2453
2454 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002455 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002456 if(pipe_info.lIndex == ovutils::OV_INVALID)
2457 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002458 }
2459
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002460 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002461 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2462 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002463 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002464 return false;
2465 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002466
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002467 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002468}
2469
Saurabh Shah88e4d272013-09-03 13:31:29 -07002470bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002471 hwc_display_contents_1_t* list) {
2472 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002473
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002474 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002475
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002476 hwc_layer_1_t* layer = &list->hwLayers[index];
2477 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302478 hwc_rect_t dst = layer->displayFrame;
2479 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302480 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302481 if((dst.left > lSplit)||(dst.right < lSplit)){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002482 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302483 continue;
2484 }
2485 }
2486 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002487 //XXX: Check for forced 2D composition
2488 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2489 if(allocSplitVGPipes(ctx,index))
2490 continue;
2491
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002492 int mdpIndex = mCurrentFrame.layerToMDP[index];
2493 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002494 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002495 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002496 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002497
Saurabh Shahc62f3982014-03-05 14:28:26 -08002498 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2499 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2500 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002501 return false;
2502 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002503 }
2504 return true;
2505}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002506
radhakrishnac9a67412013-09-25 17:40:42 +05302507int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2508 PipeLayerPair& PipeLayerPair) {
2509 const int lSplit = getLeftSplit(ctx, mDpy);
2510 hwc_rect_t dst = layer->displayFrame;
2511 if((dst.left > lSplit)||(dst.right < lSplit)){
2512 MdpYUVPipeInfo& mdp_info =
2513 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2514 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302515 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302516 eDest lDest = mdp_info.lIndex;
2517 eDest rDest = mdp_info.rIndex;
2518
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002519 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302520 lDest, rDest, &PipeLayerPair.rot);
2521 }
2522 else{
2523 return configure(ctx, layer, PipeLayerPair);
2524 }
2525}
2526
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002527/*
2528 * Configures pipe(s) for MDP composition
2529 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002530int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002531 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002532 MdpPipeInfoSplit& mdp_info =
2533 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002534 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302535 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002536 eDest lDest = mdp_info.lIndex;
2537 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002538
2539 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002540 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002541
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002542 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002543 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002544}
2545
Saurabh Shah88e4d272013-09-03 13:31:29 -07002546bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002547
Raj Kamal4393eaa2014-06-06 13:45:20 +05302548 if(!isEnabled() or !mModeOn) {
2549 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302550 return true;
2551 }
2552
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002553 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002554 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002555
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002556 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2557 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002558 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002559 if(mCurrentFrame.isFBComposed[i]) continue;
2560
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002561 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002562 private_handle_t *hnd = (private_handle_t *)layer->handle;
2563 if(!hnd) {
2564 ALOGE("%s handle null", __FUNCTION__);
2565 return false;
2566 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002567
2568 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2569 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002570 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002571
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002572 int mdpIndex = mCurrentFrame.layerToMDP[i];
2573
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002574 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2575 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302576 {
2577 MdpYUVPipeInfo& pipe_info =
2578 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2579 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2580 ovutils::eDest indexL = pipe_info.lIndex;
2581 ovutils::eDest indexR = pipe_info.rIndex;
2582 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302583 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302584 if(rot) {
2585 rot->queueBuffer(fd, offset);
2586 fd = rot->getDstMemId();
2587 offset = rot->getDstOffset();
2588 }
2589 if(indexL != ovutils::OV_INVALID) {
2590 ovutils::eDest destL = (ovutils::eDest)indexL;
2591 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2592 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2593 if (!ov.queueBuffer(fd, offset, destL)) {
2594 ALOGE("%s: queueBuffer failed for display:%d",
2595 __FUNCTION__, mDpy);
2596 return false;
2597 }
2598 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002599
radhakrishnac9a67412013-09-25 17:40:42 +05302600 if(indexR != ovutils::OV_INVALID) {
2601 ovutils::eDest destR = (ovutils::eDest)indexR;
2602 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2603 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2604 if (!ov.queueBuffer(fd, offset, destR)) {
2605 ALOGE("%s: queueBuffer failed for display:%d",
2606 __FUNCTION__, mDpy);
2607 return false;
2608 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002609 }
2610 }
radhakrishnac9a67412013-09-25 17:40:42 +05302611 else{
2612 MdpPipeInfoSplit& pipe_info =
2613 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2614 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002615
radhakrishnac9a67412013-09-25 17:40:42 +05302616 ovutils::eDest indexL = pipe_info.lIndex;
2617 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002618
radhakrishnac9a67412013-09-25 17:40:42 +05302619 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002620 uint32_t offset = (uint32_t)hnd->offset;
2621 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2622 if (!mDpy && (index != -1)) {
2623 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2624 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002625 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002626 }
radhakrishnac9a67412013-09-25 17:40:42 +05302627
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002628 if(ctx->mAD->draw(ctx, fd, offset)) {
2629 fd = ctx->mAD->getDstFd();
2630 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002631 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002632
radhakrishnac9a67412013-09-25 17:40:42 +05302633 if(rot) {
2634 rot->queueBuffer(fd, offset);
2635 fd = rot->getDstMemId();
2636 offset = rot->getDstOffset();
2637 }
2638
2639 //************* play left mixer **********
2640 if(indexL != ovutils::OV_INVALID) {
2641 ovutils::eDest destL = (ovutils::eDest)indexL;
2642 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2643 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2644 if (!ov.queueBuffer(fd, offset, destL)) {
2645 ALOGE("%s: queueBuffer failed for left mixer",
2646 __FUNCTION__);
2647 return false;
2648 }
2649 }
2650
2651 //************* play right mixer **********
2652 if(indexR != ovutils::OV_INVALID) {
2653 ovutils::eDest destR = (ovutils::eDest)indexR;
2654 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2655 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2656 if (!ov.queueBuffer(fd, offset, destR)) {
2657 ALOGE("%s: queueBuffer failed for right mixer",
2658 __FUNCTION__);
2659 return false;
2660 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002661 }
2662 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002663
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002664 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2665 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002666
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002667 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002668}
Saurabh Shahab47c692014-02-12 18:45:57 -08002669
2670//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002671
2672bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2673 hwc_display_contents_1_t* list) {
2674 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2675 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2676
2677 for(int i = numAppLayers - 1; i >= 0; i--) {
2678 if(!isValidRect(visibleRect)) {
2679 mCurrentFrame.drop[i] = true;
2680 mCurrentFrame.dropCount++;
2681 continue;
2682 }
2683
2684 const hwc_layer_1_t* layer = &list->hwLayers[i];
2685 hwc_rect_t dstRect = layer->displayFrame;
2686 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2687
2688 if(!isValidRect(res)) {
2689 mCurrentFrame.drop[i] = true;
2690 mCurrentFrame.dropCount++;
2691 } else {
2692 /* Reset frame ROI when any layer which needs scaling also needs ROI
2693 * cropping */
2694 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2695 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2696 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2697 mCurrentFrame.dropCount = 0;
2698 return false;
2699 }
2700
2701 /* deduct any opaque region from visibleRect */
2702 if (layer->blending == HWC_BLENDING_NONE &&
2703 layer->planeAlpha == 0xFF)
2704 visibleRect = deductRect(visibleRect, res);
2705 }
2706 }
2707 return true;
2708}
2709
2710/*
2711 * HW Limitation: ping pong split can always split the ping pong output
2712 * equally across two DSI's. So the ROI programmed should be of equal width
2713 * for both the halves
2714 */
2715void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2716 hwc_display_contents_1_t* list) {
2717 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2718
2719
2720 if(!canPartialUpdate(ctx, list))
2721 return;
2722
2723 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2724 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2725 (int)ctx->dpyAttr[mDpy].yres};
2726
2727 for(int index = 0; index < numAppLayers; index++ ) {
2728 hwc_layer_1_t* layer = &list->hwLayers[index];
2729
2730 // If we have a RGB layer which needs rotation, no partial update
2731 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2732 return;
2733
2734 if ((mCachedFrame.hnd[index] != layer->handle) ||
2735 isYuvBuffer((private_handle_t *)layer->handle)) {
2736 hwc_rect_t dst = layer->displayFrame;
2737 hwc_rect_t updatingRect = dst;
2738
2739#ifdef QCOM_BSP
2740 if(!needsScaling(layer) && !layer->transform)
2741 {
2742 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2743 int x_off = dst.left - src.left;
2744 int y_off = dst.top - src.top;
2745 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2746 }
2747#endif
2748
2749 roi = getUnion(roi, updatingRect);
2750 }
2751 }
2752
2753 /* No layer is updating. Still SF wants a refresh.*/
2754 if(!isValidRect(roi))
2755 return;
2756
2757 roi = expandROIFromMidPoint(roi, fullFrame);
2758
2759 hwc_rect lFrame = fullFrame;
2760 lFrame.right /= 2;
2761 hwc_rect lRoi = getIntersection(roi, lFrame);
2762
2763 // Align ROI coordinates to panel restrictions
2764 lRoi = getSanitizeROI(lRoi, lFrame);
2765
2766 hwc_rect rFrame = fullFrame;
2767 rFrame.left = lFrame.right;
2768 hwc_rect rRoi = getIntersection(roi, rFrame);
2769
2770 // Align ROI coordinates to panel restrictions
2771 rRoi = getSanitizeROI(rRoi, rFrame);
2772
2773 roi = getUnion(lRoi, rRoi);
2774
2775 ctx->listStats[mDpy].lRoi = roi;
2776 if(!validateAndApplyROI(ctx, list))
2777 resetROI(ctx, mDpy);
2778
2779 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2780 __FUNCTION__,
2781 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2782 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2783 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2784 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2785}
2786
Saurabh Shahab47c692014-02-12 18:45:57 -08002787bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002788 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002789 private_handle_t *hnd = (private_handle_t *)layer->handle;
2790 hwc_rect_t dst = layer->displayFrame;
2791 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2792 pipe_info.lIndex = ovutils::OV_INVALID;
2793 pipe_info.rIndex = ovutils::OV_INVALID;
2794
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002795 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2796 trimAgainstROI(ctx,crop, dst);
2797
Saurabh Shahab47c692014-02-12 18:45:57 -08002798 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2799 //should have a higher priority than the right one. Pipe priorities are
2800 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002801
Saurabh Shahc62f3982014-03-05 14:28:26 -08002802 Overlay::PipeSpecs pipeSpecs;
2803 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2804 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2805 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2806 pipeSpecs.dpy = mDpy;
2807 pipeSpecs.fb = false;
2808
Saurabh Shahab47c692014-02-12 18:45:57 -08002809 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002810 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002811 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002812 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002813 }
2814
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002815 /* Use 2 pipes IF
2816 a) Layer's crop width is > 2048 or
2817 b) Layer's dest width > 2048 or
2818 c) On primary, driver has indicated with caps to split always. This is
2819 based on an empirically derived value of panel height. Applied only
2820 if the layer's width is > mixer's width
2821 */
2822
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302823 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002824 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302825 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002826 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2827 const uint32_t dstWidth = dst.right - dst.left;
2828 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002829 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002830 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002831 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002832 crop.bottom - crop.top;
2833 //Approximation to actual clock, ignoring the common factors in pipe and
2834 //mixer cases like line_time
2835 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2836 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002837
Saurabh Shah05f4e222015-02-05 14:36:22 -08002838 const uint32_t downscale = getRotDownscale(ctx, layer);
2839 if(downscale) {
2840 cropWidth /= downscale;
2841 cropHeight /= downscale;
2842 }
2843
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002844 if(dstWidth > mdpHw.getMaxPipeWidth() or
2845 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002846 (primarySplitAlways and
2847 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002848 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002849 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002850 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002851 }
2852
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002853 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2854 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002855 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002856 }
2857 }
2858
2859 return true;
2860}
2861
Saurabh Shahab47c692014-02-12 18:45:57 -08002862int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2863 PipeLayerPair& PipeLayerPair) {
2864 private_handle_t *hnd = (private_handle_t *)layer->handle;
2865 if(!hnd) {
2866 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2867 return -1;
2868 }
2869 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2870 MdpPipeInfoSplit& mdp_info =
2871 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2872 Rotator **rot = &PipeLayerPair.rot;
2873 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002874 eDest lDest = mdp_info.lIndex;
2875 eDest rDest = mdp_info.rIndex;
2876 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2877 hwc_rect_t dst = layer->displayFrame;
2878 int transform = layer->transform;
2879 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002880 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002881 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002882 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002883 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08002884
2885 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2886 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2887
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002888 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2889 /* MDP driver crops layer coordinates against ROI in Non-Split
2890 * and Split MDP comp. But HWC needs to crop them for source split.
2891 * Reason: 1) Source split is efficient only when the final effective
2892 * load is distributed evenly across mixers.
2893 * 2) We have to know the effective width of the layer that
2894 * the ROI needs to find the no. of pipes the layer needs.
2895 */
2896 trimAgainstROI(ctx, crop, dst);
2897 }
2898
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002899 if(needs3DComposition(ctx, mDpy) &&
2900 get3DFormat(hnd) != HAL_NO_3D){
2901 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
2902 rDest, &PipeLayerPair.rot);
2903 }
2904
Saurabh Shahab47c692014-02-12 18:45:57 -08002905 // Handle R/B swap
2906 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2907 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2908 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2909 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2910 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2911 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002912 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002913 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2914 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002915 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002916 /* Calculate the external display position based on MDP downscale,
2917 ActionSafe, and extorientation features. */
2918 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002919
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002920 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002921 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002922
2923 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2924 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002925 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002926 }
2927
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002928 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002929 (*rot) = ctx->mRotMgr->getNext();
2930 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002931 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002932 //If the video is using a single pipe, enable BWC
2933 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002934 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2935 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002936 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002937 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002938 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002939 ALOGE("%s: configRotator failed!", __FUNCTION__);
2940 return -1;
2941 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002942 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002943 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002944 }
2945
2946 //If 2 pipes being used, divide layer into half, crop and dst
2947 hwc_rect_t cropL = crop;
2948 hwc_rect_t cropR = crop;
2949 hwc_rect_t dstL = dst;
2950 hwc_rect_t dstR = dst;
2951 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2952 cropL.right = (crop.right + crop.left) / 2;
2953 cropR.left = cropL.right;
2954 sanitizeSourceCrop(cropL, cropR, hnd);
2955
Saurabh Shahb729b192014-08-15 18:04:24 -07002956 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002957 //Swap crops on H flip since 2 pipes are being used
2958 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2959 hwc_rect_t tmp = cropL;
2960 cropL = cropR;
2961 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002962 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002963 }
2964
Saurabh Shahb729b192014-08-15 18:04:24 -07002965 //cropSwap trick: If the src and dst widths are both odd, let us say
2966 //2507, then splitting both into half would cause left width to be 1253
2967 //and right 1254. If crop is swapped because of H flip, this will cause
2968 //left crop width to be 1254, whereas left dst width remains 1253, thus
2969 //inducing a scaling that is unaccounted for. To overcome that we add 1
2970 //to the dst width if there is a cropSwap. So if the original width was
2971 //2507, the left dst width will be 1254. Even if the original width was
2972 //even for ex: 2508, the left dst width will still remain 1254.
2973 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002974 dstR.left = dstL.right;
2975 }
2976
2977 //For the mdp, since either we are pre-rotating or MDP does flips
2978 orient = OVERLAY_TRANSFORM_0;
2979 transform = 0;
2980
2981 //configure left pipe
2982 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002983 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002984 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2985 (ovutils::eBlending) getBlending(layer->blending));
2986
2987 if(configMdp(ctx->mOverlay, pargL, orient,
2988 cropL, dstL, metadata, lDest) < 0) {
2989 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2990 return -1;
2991 }
2992 }
2993
2994 //configure right pipe
2995 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002996 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002997 static_cast<eRotFlags>(rotFlags),
2998 layer->planeAlpha,
2999 (ovutils::eBlending) getBlending(layer->blending));
3000 if(configMdp(ctx->mOverlay, pargR, orient,
3001 cropR, dstR, metadata, rDest) < 0) {
3002 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3003 return -1;
3004 }
3005 }
3006
3007 return 0;
3008}
3009
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003010bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3011 Locker::Autolock _l(ctx->mDrawLock);
3012 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3013 char path[MAX_SYSFS_FILE_PATH];
3014 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3015 int fd = open(path, O_RDONLY);
3016 if(fd < 0) {
3017 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3018 return -1;
3019 }
3020 char value[4];
3021 ssize_t size_read = read(fd, value, sizeof(value)-1);
3022 if(size_read <= 0) {
3023 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3024 close(fd);
3025 return -1;
3026 }
3027 close(fd);
3028 value[size_read] = '\0';
3029 return atoi(value);
3030}
3031
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003032int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3033 Locker::Autolock _l(ctx->mDrawLock);
3034 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3035 char path[MAX_SYSFS_FILE_PATH];
3036 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3037 int fd = open(path, O_WRONLY);
3038 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003039 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003040 return -1;
3041 }
3042 char value[4];
3043 snprintf(value, sizeof(value), "%d", (int)enable);
3044 ssize_t ret = write(fd, value, strlen(value));
3045 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003046 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003047 close(fd);
3048 return -1;
3049 }
3050 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003051 return 0;
3052}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003053
3054bool MDPComp::loadPerfLib() {
3055 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3056 bool success = false;
3057 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3058 ALOGE("vendor library not set in ro.vendor.extension_library");
3059 return false;
3060 }
3061
3062 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3063 if(sLibPerfHint) {
3064 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3065 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3066 if (!sPerfLockAcquire || !sPerfLockRelease) {
3067 ALOGE("Failed to load symbols for perfLock");
3068 dlclose(sLibPerfHint);
3069 sLibPerfHint = NULL;
3070 return false;
3071 }
3072 success = true;
3073 ALOGI("Successfully Loaded perf hint API's");
3074 } else {
3075 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3076 }
3077 return success;
3078}
3079
3080void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3081 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3082 return;
3083 }
3084 static int count = sPerfHintWindow;
3085 static int perflockFlag = 0;
3086
3087 /* Send hint to mpctl when single layer is updated
3088 * for a successful number of windows. Hint release
3089 * happens immediately upon multiple layer update.
3090 */
3091 if (onlyVideosUpdating(ctx, list)) {
3092 if(count) {
3093 count--;
3094 }
3095 } else {
3096 if (perflockFlag) {
3097 perflockFlag = 0;
3098 sPerfLockRelease(sPerfLockHandle);
3099 }
3100 count = sPerfHintWindow;
3101 }
3102 if (count == 0 && !perflockFlag) {
3103 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3104 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3105 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003106 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003107 perflockFlag = 1;
3108 }
3109 }
3110}
3111
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003112}; //namespace
3113