blob: 039852eacbbc139438815674d4800f853f975e59 [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
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800464 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530465 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800466 const float w_dscale = w_scale;
467 const float h_dscale = h_scale;
468
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800469 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700470
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530471 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700472 /* On targets that doesnt support Decimation (eg.,8x26)
473 * maximum downscale support is overlay pipe downscale.
474 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800475 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530476 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700477 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800478 return false;
479 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700480 // Decimation on macrotile format layers is not supported.
481 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530482 /* Bail out if
483 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700484 * 2. exceeds maximum downscale limit
485 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800486 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530487 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700488 w_dscale > maxMDPDownscale ||
489 h_dscale > maxMDPDownscale) {
490 return false;
491 }
492 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800493 return false;
494 }
495 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700496 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700497 return false;
498 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700499 }
500
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800501 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530502 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800503 const float w_uscale = 1.0f / w_scale;
504 const float h_uscale = 1.0f / h_scale;
505
506 if(w_uscale > upscale || h_uscale > upscale)
507 return false;
508 }
509
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800510 return true;
511}
512
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800513bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700514 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800515
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800516 if(!isEnabled()) {
517 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700518 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530519 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530520 qdutils::MDPVersion::getInstance().is8x16() ||
521 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800522 ctx->mVideoTransFlag &&
523 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700524 //1 Padding round to shift pipes across mixers
525 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
526 __FUNCTION__);
527 ret = false;
Raj Kamalc0d34242015-03-17 20:53:14 +0530528 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
529 qdutils::MDPVersion::getInstance().is8x16() ||
530 qdutils::MDPVersion::getInstance().is8x39()) &&
531 !mDpy && isSecondaryAnimating(ctx) &&
532 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
533 ALOGD_IF(isDebug(),"%s: Display animation in progress",
534 __FUNCTION__);
535 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700536 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
537 /* TODO: freeing up all the resources only for the targets having total
538 number of pipes < 8. Need to analyze number of VIG pipes used
539 for primary in previous draw cycle and accordingly decide
540 whether to fall back to full GPU comp or video only comp
541 */
542 if(isSecondaryConfiguring(ctx)) {
543 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
544 __FUNCTION__);
545 ret = false;
546 } else if(ctx->isPaddingRound) {
547 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
548 __FUNCTION__,mDpy);
549 ret = false;
550 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800551 } else if (ctx->isDMAStateChanging) {
552 // Bail out if a padding round has been invoked in order to switch DMA
553 // state to block mode. We need this to cater for the case when a layer
554 // requires rotation in the current frame.
555 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
556 __FUNCTION__);
557 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700558 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800559
Saurabh Shahaa236822013-04-24 18:07:26 -0700560 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800561}
562
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800563void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
564 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800565 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800566 dst = getIntersection(dst, roi);
567 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800568}
569
570/* 1) Identify layers that are not visible or lying outside the updating ROI and
571 * drop them from composition.
572 * 2) If we have a scaling layer which needs cropping against generated
573 * ROI, reset ROI to full resolution. */
574bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
575 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700576 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800578
579 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800580 if(!isValidRect(visibleRect)) {
581 mCurrentFrame.drop[i] = true;
582 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800583 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800584 }
585
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700586 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700587 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800588 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700589
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700590 if(!isValidRect(res)) {
591 mCurrentFrame.drop[i] = true;
592 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800593 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700594 /* Reset frame ROI when any layer which needs scaling also needs ROI
595 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800596 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800597 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700598 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
599 mCurrentFrame.dropCount = 0;
600 return false;
601 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800602
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800603 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530604 if (layer->blending == HWC_BLENDING_NONE &&
605 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800606 visibleRect = deductRect(visibleRect, res);
607 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700608 }
609 return true;
610}
611
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800612/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
613 * are updating. If DirtyRegion is applicable, calculate it by accounting all
614 * the changing layer's dirtyRegion. */
615void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
616 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700617 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800618 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700619 return;
620
621 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800622 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
623 (int)ctx->dpyAttr[mDpy].yres};
624
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700625 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800626 hwc_layer_1_t* layer = &list->hwLayers[index];
627 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800628 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700629 hwc_rect_t dst = layer->displayFrame;
630 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800631
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800632#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530633 if(!needsScaling(layer) && !layer->transform &&
634 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700635 {
636 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
637 int x_off = dst.left - src.left;
638 int y_off = dst.top - src.top;
639 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
640 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800641#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800642
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800643 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700644 }
645 }
646
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800647 /* No layer is updating. Still SF wants a refresh.*/
648 if(!isValidRect(roi))
649 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800650
651 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800652 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800653
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800654 ctx->listStats[mDpy].lRoi = roi;
655 if(!validateAndApplyROI(ctx, list))
656 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700657
658 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800659 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
660 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
661}
662
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800663void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
664 hwc_rect &dst) {
665 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
666 ctx->listStats[mDpy].rRoi);
667 hwc_rect tmpDst = getIntersection(dst, roi);
668 if(!isSameRect(dst, tmpDst)) {
669 crop.left = crop.left + (tmpDst.left - dst.left);
670 crop.top = crop.top + (tmpDst.top - dst.top);
671 crop.right = crop.left + (tmpDst.right - tmpDst.left);
672 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
673 dst = tmpDst;
674 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800675}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800676
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800677/* 1) Identify layers that are not visible or lying outside BOTH the updating
678 * ROI's and drop them from composition. If a layer is spanning across both
679 * the halves of the screen but needed by only ROI, the non-contributing
680 * half will not be programmed for MDP.
681 * 2) If we have a scaling layer which needs cropping against generated
682 * ROI, reset ROI to full resolution. */
683bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
684 hwc_display_contents_1_t* list) {
685
686 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
687
688 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
689 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
690
691 for(int i = numAppLayers - 1; i >= 0; i--){
692 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
693 {
694 mCurrentFrame.drop[i] = true;
695 mCurrentFrame.dropCount++;
696 continue;
697 }
698
699 const hwc_layer_1_t* layer = &list->hwLayers[i];
700 hwc_rect_t dstRect = layer->displayFrame;
701
702 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
703 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
704 hwc_rect_t res = getUnion(l_res, r_res);
705
706 if(!isValidRect(l_res) && !isValidRect(r_res)) {
707 mCurrentFrame.drop[i] = true;
708 mCurrentFrame.dropCount++;
709 } else {
710 /* Reset frame ROI when any layer which needs scaling also needs ROI
711 * cropping */
712 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
713 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
714 mCurrentFrame.dropCount = 0;
715 return false;
716 }
717
radhakrishna4efbdd62014-11-03 13:19:27 +0530718 if (layer->blending == HWC_BLENDING_NONE &&
719 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800720 visibleRectL = deductRect(visibleRectL, l_res);
721 visibleRectR = deductRect(visibleRectR, r_res);
722 }
723 }
724 }
725 return true;
726}
727/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
728 * are updating. If DirtyRegion is applicable, calculate it by accounting all
729 * the changing layer's dirtyRegion. */
730void MDPCompSplit::generateROI(hwc_context_t *ctx,
731 hwc_display_contents_1_t* list) {
732 if(!canPartialUpdate(ctx, list))
733 return;
734
735 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
736 int lSplit = getLeftSplit(ctx, mDpy);
737
738 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
739 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
740
741 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
742 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
743
744 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
745 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
746
747 for(int index = 0; index < numAppLayers; index++ ) {
748 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800749 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800750 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800751 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700752 hwc_rect_t dst = layer->displayFrame;
753 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800754
755#ifdef QCOM_BSP
756 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700757 {
758 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
759 int x_off = dst.left - src.left;
760 int y_off = dst.top - src.top;
761 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
762 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800763#endif
764
765 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
766 if(isValidRect(l_dst))
767 l_roi = getUnion(l_roi, l_dst);
768
769 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
770 if(isValidRect(r_dst))
771 r_roi = getUnion(r_roi, r_dst);
772 }
773 }
774
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700775 /* For panels that cannot accept commands in both the interfaces, we cannot
776 * send two ROI's (for each half). We merge them into single ROI and split
777 * them across lSplit for MDP mixer use. The ROI's will be merged again
778 * finally before udpating the panel in the driver. */
779 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
780 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
781 l_roi = getIntersection(temp_roi, l_frame);
782 r_roi = getIntersection(temp_roi, r_frame);
783 }
784
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800785 /* No layer is updating. Still SF wants a refresh. */
786 if(!isValidRect(l_roi) && !isValidRect(r_roi))
787 return;
788
789 l_roi = getSanitizeROI(l_roi, l_frame);
790 r_roi = getSanitizeROI(r_roi, r_frame);
791
792 ctx->listStats[mDpy].lRoi = l_roi;
793 ctx->listStats[mDpy].rRoi = r_roi;
794
795 if(!validateAndApplyROI(ctx, list))
796 resetROI(ctx, mDpy);
797
798 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
799 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
800 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
801 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
802 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
803 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700804}
805
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800806/* Checks for conditions where all the layers marked for MDP comp cannot be
807 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800808bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800809 hwc_display_contents_1_t* list){
810
Saurabh Shahaa236822013-04-24 18:07:26 -0700811 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800812
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700813 // Fall back to video only composition, if AIV video mode is enabled
814 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700815 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
816 __FUNCTION__, mDpy);
817 return false;
818 }
819
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530820 /* No Idle fall back if secure display or secure RGB layers are present
821 * or if there is only a single layer being composed */
822 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
823 !ctx->listStats[mDpy].secureRGBCount &&
824 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700825 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
826 return false;
827 }
828
Raj Kamalc0d34242015-03-17 20:53:14 +0530829 if(!mDpy && isSecondaryAnimating(ctx) &&
830 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
831 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
832 ALOGD_IF(isDebug(),"%s: Display animation in progress",
833 __FUNCTION__);
834 return false;
835 }
836
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700837 // if secondary is configuring or Padding round, fall back to video only
838 // composition and release all assigned non VIG pipes from primary.
839 if(isSecondaryConfiguring(ctx)) {
840 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
841 __FUNCTION__);
842 return false;
843 } else if(ctx->isPaddingRound) {
844 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
845 __FUNCTION__,mDpy);
846 return false;
847 }
848
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500849 // No MDP composition for 3D
850 if(needs3DComposition(ctx, mDpy))
851 return false;
852
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700853 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800854 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700855 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800856 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
857 return false;
858 }
859
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800860 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800861 hwc_layer_1_t* layer = &list->hwLayers[i];
862 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800863
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800864 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700865 if(!canUseRotator(ctx, mDpy)) {
866 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
867 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700868 return false;
869 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800870 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530871
872 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
873 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800874 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700875 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530876 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
877 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
878 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800879 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700880
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700881 if(ctx->mAD->isDoable()) {
882 return false;
883 }
884
Saurabh Shahaa236822013-04-24 18:07:26 -0700885 //If all above hard conditions are met we can do full or partial MDP comp.
886 bool ret = false;
887 if(fullMDPComp(ctx, list)) {
888 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700889 } else if(fullMDPCompWithPTOR(ctx, list)) {
890 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700891 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700892 ret = true;
893 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530894
Saurabh Shahaa236822013-04-24 18:07:26 -0700895 return ret;
896}
897
898bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700899
900 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
901 return false;
902
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700903 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
904 for(int i = 0; i < numAppLayers; i++) {
905 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700906 if(not mCurrentFrame.drop[i] and
907 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700908 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
909 return false;
910 }
911 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800912
Saurabh Shahaa236822013-04-24 18:07:26 -0700913 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700914 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
915 sizeof(mCurrentFrame.isFBComposed));
916 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
917 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700918
Raj Kamal389d6e32014-08-04 14:43:24 +0530919 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800920 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530921 }
922
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800923 if(!postHeuristicsHandling(ctx, list)) {
924 ALOGD_IF(isDebug(), "post heuristic handling failed");
925 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700926 return false;
927 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700928 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
929 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700930 return true;
931}
932
Sushil Chauhandefd3522014-05-13 18:17:12 -0700933/* Full MDP Composition with Peripheral Tiny Overlap Removal.
934 * MDP bandwidth limitations can be avoided, if the overlap region
935 * covered by the smallest layer at a higher z-order, gets composed
936 * by Copybit on a render buffer, which can be queued to MDP.
937 */
938bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
939 hwc_display_contents_1_t* list) {
940
941 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
942 const int stagesForMDP = min(sMaxPipesPerMixer,
943 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
944
945 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700946 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700947 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
948 return false;
949 }
950
951 // Frame level checks
952 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
953 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
954 isSecurePresent(ctx, mDpy)) {
955 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
956 return false;
957 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700958 // MDP comp checks
959 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700960 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700961 if(not isSupportedForMDPComp(ctx, layer)) {
962 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
963 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700964 }
965 }
966
Sushil Chauhandefd3522014-05-13 18:17:12 -0700967 /* We cannot use this composition mode, if:
968 1. A below layer needs scaling.
969 2. Overlap is not peripheral to display.
970 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700971 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700972 */
973
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700974 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
975 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
976 memset(overlapRect, 0, sizeof(overlapRect));
977 int layerPixelCount, minPixelCount = 0;
978 int numPTORLayersFound = 0;
979 for (int i = numAppLayers-1; (i >= 0 &&
980 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700981 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700982 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700983 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700984 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
985 // PTOR layer should be peripheral and cannot have transform
986 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
987 has90Transform(layer)) {
988 continue;
989 }
990 if((3 * (layerPixelCount + minPixelCount)) >
991 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
992 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
993 continue;
994 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700995 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700996 for (int j = i-1; j >= 0; j--) {
997 // Check if the layers below this layer qualifies for PTOR comp
998 hwc_layer_1_t* layer = &list->hwLayers[j];
999 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001000 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001001 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001002 if (isValidRect(getIntersection(dispFrame, disFrame))) {
1003 if (has90Transform(layer) || needsScaling(layer)) {
1004 found = false;
1005 break;
1006 }
1007 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001008 }
1009 }
1010 // Store the minLayer Index
1011 if(found) {
1012 minLayerIndex[numPTORLayersFound] = i;
1013 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1014 minPixelCount += layerPixelCount;
1015 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001016 }
1017 }
1018
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001019 // No overlap layers
1020 if (!numPTORLayersFound)
1021 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001022
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001023 // Store the displayFrame and the sourceCrops of the layers
1024 hwc_rect_t displayFrame[numAppLayers];
1025 hwc_rect_t sourceCrop[numAppLayers];
1026 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001027 hwc_layer_1_t* layer = &list->hwLayers[i];
1028 displayFrame[i] = layer->displayFrame;
1029 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001030 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001031
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301032 /**
1033 * It's possible that 2 PTOR layers might have overlapping.
1034 * In such case, remove the intersection(again if peripheral)
1035 * from the lower PTOR layer to avoid overlapping.
1036 * If intersection is not on peripheral then compromise
1037 * by reducing number of PTOR layers.
1038 **/
1039 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1040 if(isValidRect(commonRect)) {
1041 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1042 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1043 }
1044
1045 ctx->mPtorInfo.count = numPTORLayersFound;
1046 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1047 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1048 }
1049
1050 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1051 // reset PTOR
1052 ctx->mPtorInfo.count = 0;
1053 if(isValidRect(commonRect)) {
1054 // If PTORs are intersecting restore displayframe of PTOR[1]
1055 // before returning, as we have modified it above.
1056 list->hwLayers[minLayerIndex[1]].displayFrame =
1057 displayFrame[minLayerIndex[1]];
1058 }
1059 return false;
1060 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001061 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1062 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1063
Xu Yangcda012c2014-07-30 21:57:21 +08001064 // Store the blending mode, planeAlpha, and transform of PTOR layers
1065 int32_t blending[numPTORLayersFound];
1066 uint8_t planeAlpha[numPTORLayersFound];
1067 uint32_t transform[numPTORLayersFound];
1068
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001069 for(int j = 0; j < numPTORLayersFound; j++) {
1070 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001071
1072 // Update src crop of PTOR layer
1073 hwc_layer_1_t* layer = &list->hwLayers[index];
1074 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1075 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1076 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1077 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1078
1079 // Store & update w, h, format of PTOR layer
1080 private_handle_t *hnd = (private_handle_t *)layer->handle;
1081 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1082 layerWhf[j] = whf;
1083 hnd->width = renderBuf->width;
1084 hnd->height = renderBuf->height;
1085 hnd->format = renderBuf->format;
1086
Xu Yangcda012c2014-07-30 21:57:21 +08001087 // Store & update blending mode, planeAlpha and transform of PTOR layer
1088 blending[j] = layer->blending;
1089 planeAlpha[j] = layer->planeAlpha;
1090 transform[j] = layer->transform;
1091 layer->blending = HWC_BLENDING_NONE;
1092 layer->planeAlpha = 0xFF;
1093 layer->transform = 0;
1094
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001095 // Remove overlap from crop & displayFrame of below layers
1096 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001097 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001098 if(!isValidRect(getIntersection(layer->displayFrame,
1099 overlapRect[j]))) {
1100 continue;
1101 }
1102 // Update layer attributes
1103 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1104 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301105 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001106 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1107 layer->transform);
1108 layer->sourceCropf.left = (float)srcCrop.left;
1109 layer->sourceCropf.top = (float)srcCrop.top;
1110 layer->sourceCropf.right = (float)srcCrop.right;
1111 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1112 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001113 }
1114
1115 mCurrentFrame.mdpCount = numAppLayers;
1116 mCurrentFrame.fbCount = 0;
1117 mCurrentFrame.fbZ = -1;
1118
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301119 for (int j = 0; j < numAppLayers; j++) {
1120 if(isValidRect(list->hwLayers[j].displayFrame)) {
1121 mCurrentFrame.isFBComposed[j] = false;
1122 } else {
1123 mCurrentFrame.mdpCount--;
1124 mCurrentFrame.drop[j] = true;
1125 }
1126 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001127
1128 bool result = postHeuristicsHandling(ctx, list);
1129
1130 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001131 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001132 hwc_layer_1_t* layer = &list->hwLayers[i];
1133 layer->displayFrame = displayFrame[i];
1134 layer->sourceCropf.left = (float)sourceCrop[i].left;
1135 layer->sourceCropf.top = (float)sourceCrop[i].top;
1136 layer->sourceCropf.right = (float)sourceCrop[i].right;
1137 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1138 }
1139
Xu Yangcda012c2014-07-30 21:57:21 +08001140 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001141 for (int i = 0; i < numPTORLayersFound; i++) {
1142 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001143 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001144 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1145 hnd->width = layerWhf[i].w;
1146 hnd->height = layerWhf[i].h;
1147 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001148 layer->blending = blending[i];
1149 layer->planeAlpha = planeAlpha[i];
1150 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001151 }
1152
Sushil Chauhandefd3522014-05-13 18:17:12 -07001153 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001154 // reset PTOR
1155 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001156 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001157 } else {
1158 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1159 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001160 }
1161
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001162 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1163 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001164 return result;
1165}
1166
Saurabh Shahaa236822013-04-24 18:07:26 -07001167bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1168{
radhakrishnac3198ff2015-03-10 17:10:02 +05301169 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1170 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001171 return false;
1172 }
1173
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001174 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301175 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1176 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001177 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001178 cacheBasedComp(ctx, list);
1179 } else {
1180 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001181 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001182 }
1183
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001184 return ret;
1185}
1186
1187bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1188 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001189 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1190 return false;
1191
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001192 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001193 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001194 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001195
1196 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1197 for(int i = 0; i < numAppLayers; i++) {
1198 if(!mCurrentFrame.isFBComposed[i]) {
1199 hwc_layer_1_t* layer = &list->hwLayers[i];
1200 if(not isSupportedForMDPComp(ctx, layer)) {
1201 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1202 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001203 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001204 return false;
1205 }
1206 }
1207 }
1208
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001209 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001210 /* mark secure RGB layers for MDP comp */
1211 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301212 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001213 if(!ret) {
1214 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001215 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001216 return false;
1217 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001218
1219 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001220
Raj Kamal389d6e32014-08-04 14:43:24 +05301221 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001222 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301223 }
1224
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001225 if(!postHeuristicsHandling(ctx, list)) {
1226 ALOGD_IF(isDebug(), "post heuristic handling failed");
1227 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001228 return false;
1229 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001230 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1231 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001232
Saurabh Shahaa236822013-04-24 18:07:26 -07001233 return true;
1234}
1235
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001236bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001237 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001238 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1239 return false;
1240
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001241 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001242 return false;
1243 }
1244
Saurabh Shahb772ae32013-11-18 15:40:02 -08001245 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001246 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1247 const int stagesForMDP = min(sMaxPipesPerMixer,
1248 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001249
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001250 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1251 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1252 int lastMDPSupportedIndex = numAppLayers;
1253 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001254
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001255 //Find the minimum MDP batch size
1256 for(int i = 0; i < numAppLayers;i++) {
1257 if(mCurrentFrame.drop[i]) {
1258 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001259 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001260 }
1261 hwc_layer_1_t* layer = &list->hwLayers[i];
1262 if(not isSupportedForMDPComp(ctx, layer)) {
1263 lastMDPSupportedIndex = i;
1264 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1265 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001266 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001267 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001268 }
1269
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001270 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1271 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1272 mCurrentFrame.dropCount);
1273
1274 //Start at a point where the fb batch should at least have 2 layers, for
1275 //this mode to be justified.
1276 while(fbBatchSize < 2) {
1277 ++fbBatchSize;
1278 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001279 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001280
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001281 //If there are no layers for MDP, this mode doesnt make sense.
1282 if(mdpBatchSize < 1) {
1283 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1284 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001285 return false;
1286 }
1287
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001288 mCurrentFrame.reset(numAppLayers);
1289
1290 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1291 while(mdpBatchSize > 0) {
1292 //Mark layers for MDP comp
1293 int mdpBatchLeft = mdpBatchSize;
1294 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1295 if(mCurrentFrame.drop[i]) {
1296 continue;
1297 }
1298 mCurrentFrame.isFBComposed[i] = false;
1299 --mdpBatchLeft;
1300 }
1301
1302 mCurrentFrame.fbZ = mdpBatchSize;
1303 mCurrentFrame.fbCount = fbBatchSize;
1304 mCurrentFrame.mdpCount = mdpBatchSize;
1305
1306 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1307 __FUNCTION__, mdpBatchSize, fbBatchSize,
1308 mCurrentFrame.dropCount);
1309
1310 if(postHeuristicsHandling(ctx, list)) {
1311 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001312 __FUNCTION__);
1313 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1314 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001315 return true;
1316 }
1317
1318 reset(ctx);
1319 --mdpBatchSize;
1320 ++fbBatchSize;
1321 }
1322
1323 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001324}
1325
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001326bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301327 if(mDpy or isSecurePresent(ctx, mDpy) or
1328 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001329 return false;
1330 }
1331 return true;
1332}
1333
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001334bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1335 hwc_display_contents_1_t* list){
1336 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1337 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001338 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001339 return false;
1340 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001341 if(ctx->listStats[mDpy].secureUI)
1342 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001343 return true;
1344}
1345
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001346bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1347 hwc_display_contents_1_t* list) {
1348 const bool secureOnly = true;
1349 return videoOnlyComp(ctx, list, not secureOnly) or
1350 videoOnlyComp(ctx, list, secureOnly);
1351}
1352
1353bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001354 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001355 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1356 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301357
Saurabh Shahaa236822013-04-24 18:07:26 -07001358 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301359 if(!isSecurePresent(ctx, mDpy)) {
1360 /* Bail out if we are processing only secured video layers
1361 * and we dont have any */
1362 if(secureOnly) {
1363 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1364 return false;
1365 }
1366 /* No Idle fall back for secure video layers and if there is only
1367 * single layer being composed. */
1368 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1369 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1370 return false;
1371 }
1372 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001373
Saurabh Shahaa236822013-04-24 18:07:26 -07001374 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001375 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001376 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001377 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001378
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001379 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1380 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001381 return false;
1382 }
1383
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001384 if(mCurrentFrame.fbCount)
1385 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001386
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001387 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001388 adjustForSourceSplit(ctx, list);
1389 }
1390
1391 if(!postHeuristicsHandling(ctx, list)) {
1392 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301393 if(errno == ENOBUFS) {
1394 ALOGD_IF(isDebug(), "SMP Allocation failed");
1395 //On SMP allocation failure in video only comp add padding round
1396 ctx->isPaddingRound = true;
1397 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001398 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001399 return false;
1400 }
1401
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001402 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1403 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001404 return true;
1405}
1406
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001407/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1408bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1409 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001410 // Fall back to video only composition, if AIV video mode is enabled
1411 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001412 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1413 __FUNCTION__, mDpy);
1414 return false;
1415 }
1416
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001417 // No MDP composition for 3D
1418 if(needs3DComposition(ctx,mDpy))
1419 return false;
1420
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001421 const bool secureOnly = true;
1422 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1423 mdpOnlyLayersComp(ctx, list, secureOnly);
1424
1425}
1426
1427bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1428 hwc_display_contents_1_t* list, bool secureOnly) {
1429
1430 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1431 return false;
1432
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301433 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1434 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1435 /* Bail out if we are processing only secured video/ui layers
1436 * and we dont have any */
1437 if(secureOnly) {
1438 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1439 return false;
1440 }
1441 /* No Idle fall back for secure video/ui layers and if there is only
1442 * single layer being composed. */
1443 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1444 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1445 return false;
1446 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001447 }
1448
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001449 /* Bail out if we dont have any secure RGB layers */
1450 if (!ctx->listStats[mDpy].secureRGBCount) {
1451 reset(ctx);
1452 return false;
1453 }
1454
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001455 mCurrentFrame.reset(numAppLayers);
1456 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1457
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001458 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001459 /* mark secure RGB layers for MDP comp */
1460 updateSecureRGB(ctx, list);
1461
1462 if(mCurrentFrame.mdpCount == 0) {
1463 reset(ctx);
1464 return false;
1465 }
1466
1467 /* find the maximum batch of layers to be marked for framebuffer */
1468 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1469 if(!ret) {
1470 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1471 reset(ctx);
1472 return false;
1473 }
1474
1475 if(sEnableYUVsplit){
1476 adjustForSourceSplit(ctx, list);
1477 }
1478
1479 if(!postHeuristicsHandling(ctx, list)) {
1480 ALOGD_IF(isDebug(), "post heuristic handling failed");
1481 reset(ctx);
1482 return false;
1483 }
1484
1485 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1486 __FUNCTION__);
1487 return true;
1488}
1489
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001490/* Checks for conditions where YUV layers cannot be bypassed */
1491bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001492 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001493 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001494 return false;
1495 }
1496
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001497 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001498 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1499 return false;
1500 }
1501
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001502 if(isSecuring(ctx, layer)) {
1503 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1504 return false;
1505 }
1506
Saurabh Shah4fdde762013-04-30 18:47:33 -07001507 if(!isValidDimension(ctx, layer)) {
1508 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1509 __FUNCTION__);
1510 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001511 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001512
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001513 if(layer->planeAlpha < 0xFF) {
1514 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1515 in video only mode",
1516 __FUNCTION__);
1517 return false;
1518 }
1519
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001520 return true;
1521}
1522
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001523/* Checks for conditions where Secure RGB layers cannot be bypassed */
1524bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1525 if(isSkipLayer(layer)) {
1526 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1527 __FUNCTION__, mDpy);
1528 return false;
1529 }
1530
1531 if(isSecuring(ctx, layer)) {
1532 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1533 return false;
1534 }
1535
1536 if(not isSupportedForMDPComp(ctx, layer)) {
1537 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1538 __FUNCTION__);
1539 return false;
1540 }
1541 return true;
1542}
1543
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301544/* starts at fromIndex and check for each layer to find
1545 * if it it has overlapping with any Updating layer above it in zorder
1546 * till the end of the batch. returns true if it finds any intersection */
1547bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1548 int fromIndex, int toIndex) {
1549 for(int i = fromIndex; i < toIndex; i++) {
1550 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1551 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1552 return false;
1553 }
1554 }
1555 }
1556 return true;
1557}
1558
1559/* Checks if given layer at targetLayerIndex has any
1560 * intersection with all the updating layers in beween
1561 * fromIndex and toIndex. Returns true if it finds intersectiion */
1562bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1563 int fromIndex, int toIndex, int targetLayerIndex) {
1564 for(int i = fromIndex; i <= toIndex; i++) {
1565 if(!mCurrentFrame.isFBComposed[i]) {
1566 if(areLayersIntersecting(&list->hwLayers[i],
1567 &list->hwLayers[targetLayerIndex])) {
1568 return true;
1569 }
1570 }
1571 }
1572 return false;
1573}
1574
1575int MDPComp::getBatch(hwc_display_contents_1_t* list,
1576 int& maxBatchStart, int& maxBatchEnd,
1577 int& maxBatchCount) {
1578 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301579 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001580 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301581 while (i < mCurrentFrame.layerCount) {
1582 int batchCount = 0;
1583 int batchStart = i;
1584 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001585 /* Adjust batch Z order with the dropped layers so far */
1586 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301587 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301588 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301589 while(i < mCurrentFrame.layerCount) {
1590 if(!mCurrentFrame.isFBComposed[i]) {
1591 if(!batchCount) {
1592 i++;
1593 break;
1594 }
1595 updatingLayersAbove++;
1596 i++;
1597 continue;
1598 } else {
1599 if(mCurrentFrame.drop[i]) {
1600 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001601 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301602 continue;
1603 } else if(updatingLayersAbove <= 0) {
1604 batchCount++;
1605 batchEnd = i;
1606 i++;
1607 continue;
1608 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1609
1610 // We have a valid updating layer already. If layer-i not
1611 // have overlapping with all updating layers in between
1612 // batch-start and i, then we can add layer i to batch.
1613 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1614 batchCount++;
1615 batchEnd = i;
1616 i++;
1617 continue;
1618 } else if(canPushBatchToTop(list, batchStart, i)) {
1619 //If All the non-updating layers with in this batch
1620 //does not have intersection with the updating layers
1621 //above in z-order, then we can safely move the batch to
1622 //higher z-order. Increment fbZ as it is moving up.
1623 if( firstZReverseIndex < 0) {
1624 firstZReverseIndex = i;
1625 }
1626 batchCount++;
1627 batchEnd = i;
1628 fbZ += updatingLayersAbove;
1629 i++;
1630 updatingLayersAbove = 0;
1631 continue;
1632 } else {
1633 //both failed.start the loop again from here.
1634 if(firstZReverseIndex >= 0) {
1635 i = firstZReverseIndex;
1636 }
1637 break;
1638 }
1639 }
1640 }
1641 }
1642 if(batchCount > maxBatchCount) {
1643 maxBatchCount = batchCount;
1644 maxBatchStart = batchStart;
1645 maxBatchEnd = batchEnd;
1646 fbZOrder = fbZ;
1647 }
1648 }
1649 return fbZOrder;
1650}
1651
1652bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1653 hwc_display_contents_1_t* list) {
1654 /* Idea is to keep as many non-updating(cached) layers in FB and
1655 * send rest of them through MDP. This is done in 2 steps.
1656 * 1. Find the maximum contiguous batch of non-updating layers.
1657 * 2. See if we can improve this batch size for caching by adding
1658 * opaque layers around the batch, if they don't have
1659 * any overlapping with the updating layers in between.
1660 * NEVER mark an updating layer for caching.
1661 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662
1663 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001664 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001665 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301666 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001667
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001668 /* Nothing is cached. No batching needed */
1669 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001670 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001671 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001672
1673 /* No MDP comp layers, try to use other comp modes */
1674 if(mCurrentFrame.mdpCount == 0) {
1675 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001676 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001677
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301678 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001679
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301680 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001682 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001683 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301684 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001685 if(!mCurrentFrame.drop[i]){
1686 //If an unsupported layer is being attempted to
1687 //be pulled out we should fail
1688 if(not isSupportedForMDPComp(ctx, layer)) {
1689 return false;
1690 }
1691 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001692 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693 }
1694 }
1695
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301696 // update the frame data
1697 mCurrentFrame.fbZ = fbZ;
1698 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001699 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001700 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001701
1702 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301703 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001704
1705 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001706}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001707
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001709 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001711 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001712
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001713 for(int i = 0; i < numAppLayers; i++) {
1714 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001715 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001716 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001717 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001718 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001719 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001720 }
1721 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001722
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001723 frame.fbCount = fbCount;
1724 frame.mdpCount = frame.layerCount - frame.fbCount
1725 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001726
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001727 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1728 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001729}
1730
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001731// drop other non-AIV layers from external display list.
1732void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001733 hwc_display_contents_1_t* list) {
1734 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1735 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001736 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001737 mCurrentFrame.dropCount++;
1738 mCurrentFrame.drop[i] = true;
1739 }
1740 }
1741 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1742 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1743 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1744 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1745 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1746 mCurrentFrame.dropCount);
1747}
1748
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001749void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001750 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001751 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1752 for(int index = 0;index < nYuvCount; index++){
1753 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1754 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1755
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001756 if(mCurrentFrame.drop[nYuvIndex]) {
1757 continue;
1758 }
1759
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001760 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001761 if(!frame.isFBComposed[nYuvIndex]) {
1762 frame.isFBComposed[nYuvIndex] = true;
1763 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001764 }
1765 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001766 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001767 private_handle_t *hnd = (private_handle_t *)layer->handle;
1768 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001769 frame.isFBComposed[nYuvIndex] = false;
1770 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001771 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001772 }
1773 }
1774 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001775
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001776 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1777 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001778}
1779
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001780void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1781 hwc_display_contents_1_t* list) {
1782 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1783 for(int index = 0;index < nSecureRGBCount; index++){
1784 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1785 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1786
1787 if(!isSecureRGBDoable(ctx, layer)) {
1788 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1789 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1790 mCurrentFrame.fbCount++;
1791 }
1792 } else {
1793 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1794 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1795 mCurrentFrame.fbCount--;
1796 }
1797 }
1798 }
1799
1800 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1801 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1802 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1803 mCurrentFrame.fbCount);
1804}
1805
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001806hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1807 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001808 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001809
1810 /* Update only the region of FB needed for composition */
1811 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1812 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1813 hwc_layer_1_t* layer = &list->hwLayers[i];
1814 hwc_rect_t dst = layer->displayFrame;
1815 fbRect = getUnion(fbRect, dst);
1816 }
1817 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001818 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001819 return fbRect;
1820}
1821
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001822bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1823 hwc_display_contents_1_t* list) {
1824
1825 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001826 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001827 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1828 return false;
1829 }
1830
1831 //Limitations checks
1832 if(!hwLimitationsCheck(ctx, list)) {
1833 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1834 return false;
1835 }
1836
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001837 //Configure framebuffer first if applicable
1838 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001839 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001840 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1841 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001842 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1843 __FUNCTION__);
1844 return false;
1845 }
1846 }
1847
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001848 mCurrentFrame.map();
1849
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001850 if(!allocLayerPipes(ctx, list)) {
1851 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001852 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001853 }
1854
1855 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001856 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001857 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001858 int mdpIndex = mCurrentFrame.layerToMDP[index];
1859 hwc_layer_1_t* layer = &list->hwLayers[index];
1860
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301861 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1862 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1863 mdpNextZOrder++;
1864 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001865 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1866 cur_pipe->zOrder = mdpNextZOrder++;
1867
radhakrishnac9a67412013-09-25 17:40:42 +05301868 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301869 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301870 if(configure4k2kYuv(ctx, layer,
1871 mCurrentFrame.mdpToLayer[mdpIndex])
1872 != 0 ){
1873 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1874 for layer %d",__FUNCTION__, index);
1875 return false;
1876 }
1877 else{
1878 mdpNextZOrder++;
1879 }
1880 continue;
1881 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001882 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1883 mdpNextZOrder++;
1884 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001885 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1886 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301887 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001888 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001889 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001890 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001891 }
1892
Saurabh Shaha36be922013-12-16 18:18:39 -08001893 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1894 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1895 ,__FUNCTION__, mDpy);
1896 return false;
1897 }
1898
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001899 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001900 return true;
1901}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001902
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001903bool MDPComp::resourceCheck(hwc_context_t* ctx,
1904 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001905 const bool fbUsed = mCurrentFrame.fbCount;
1906 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1907 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1908 return false;
1909 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001910
1911 //Will benefit cases where a video has non-updating background.
1912 if((mDpy > HWC_DISPLAY_PRIMARY) and
1913 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1914 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1915 return false;
1916 }
1917
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001918 // Init rotCount to number of rotate sessions used by other displays
1919 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1920 // Count the number of rotator sessions required for current display
1921 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1922 if(!mCurrentFrame.isFBComposed[index]) {
1923 hwc_layer_1_t* layer = &list->hwLayers[index];
1924 private_handle_t *hnd = (private_handle_t *)layer->handle;
1925 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1926 rotCount++;
1927 }
1928 }
1929 }
1930 // if number of layers to rotate exceeds max rotator sessions, bail out.
1931 if(rotCount > RotMgr::MAX_ROT_SESS) {
1932 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1933 __FUNCTION__, mDpy);
1934 return false;
1935 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001936 return true;
1937}
1938
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301939bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1940 hwc_display_contents_1_t* list) {
1941
1942 //A-family hw limitation:
1943 //If a layer need alpha scaling, MDP can not support.
1944 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1945 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1946 if(!mCurrentFrame.isFBComposed[i] &&
1947 isAlphaScaled( &list->hwLayers[i])) {
1948 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1949 return false;
1950 }
1951 }
1952 }
1953
1954 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1955 //If multiple layers requires downscaling and also they are overlapping
1956 //fall back to GPU since MDSS can not handle it.
1957 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1958 qdutils::MDPVersion::getInstance().is8x26()) {
1959 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1960 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1961 if(!mCurrentFrame.isFBComposed[i] &&
1962 isDownscaleRequired(botLayer)) {
1963 //if layer-i is marked for MDP and needs downscaling
1964 //check if any MDP layer on top of i & overlaps with layer-i
1965 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1966 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1967 if(!mCurrentFrame.isFBComposed[j] &&
1968 isDownscaleRequired(topLayer)) {
1969 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1970 topLayer->displayFrame);
1971 if(isValidRect(r))
1972 return false;
1973 }
1974 }
1975 }
1976 }
1977 }
1978 return true;
1979}
1980
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001981// Checks only if videos or single layer(RGB) is updating
1982// which is used for setting dynamic fps or perf hint for single
1983// layer video playback
1984bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1985 hwc_display_contents_1_t* list) {
1986 bool support = false;
1987 FrameInfo frame;
1988 frame.reset(mCurrentFrame.layerCount);
1989 memset(&frame.drop, 0, sizeof(frame.drop));
1990 frame.dropCount = 0;
1991 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1992 updateLayerCache(ctx, list, frame);
1993 updateYUV(ctx, list, false /*secure only*/, frame);
1994 // There are only updating YUV layers or there is single RGB
1995 // Layer(Youtube)
1996 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1997 (frame.layerCount == 1)) {
1998 support = true;
1999 }
2000 return support;
2001}
2002
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302003void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2004 //For primary display, set the dynamic refreshrate
2005 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
2006 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302007 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2008 MDPVersion& mdpHw = MDPVersion::getInstance();
2009 if(sIdleFallBack) {
2010 //Set minimum panel refresh rate during idle timeout
2011 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002012 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302013 //Set the new fresh rate, if there is only one updating YUV layer
2014 //or there is one single RGB layer with this request
2015 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2016 }
2017 setRefreshRate(ctx, mDpy, refreshRate);
2018 }
2019}
2020
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002021int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002022 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002023 char property[PROPERTY_VALUE_MAX];
2024
Raj Kamal4393eaa2014-06-06 13:45:20 +05302025 if(!ctx || !list) {
2026 ALOGE("%s: Invalid context or list",__FUNCTION__);
2027 mCachedFrame.reset();
2028 return -1;
2029 }
2030
2031 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002032 if(mDpy == HWC_DISPLAY_PRIMARY) {
2033 sSimulationFlags = 0;
2034 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2035 int currentFlags = atoi(property);
2036 if(currentFlags != sSimulationFlags) {
2037 sSimulationFlags = currentFlags;
2038 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2039 sSimulationFlags, sSimulationFlags);
2040 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002041 }
2042 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002043 // reset PTOR
2044 if(!mDpy)
2045 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002046
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302047 //reset old data
2048 mCurrentFrame.reset(numLayers);
2049 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2050 mCurrentFrame.dropCount = 0;
2051
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302052 //Do not cache the information for next draw cycle.
2053 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2054 ALOGI("%s: Unsupported layer count for mdp composition",
2055 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002056 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302057#ifdef DYNAMIC_FPS
2058 setDynRefreshRate(ctx, list);
2059#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002060 return -1;
2061 }
2062
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002063 // Detect the start of animation and fall back to GPU only once to cache
2064 // all the layers in FB and display FB content untill animation completes.
2065 if(ctx->listStats[mDpy].isDisplayAnimating) {
2066 mCurrentFrame.needsRedraw = false;
2067 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2068 mCurrentFrame.needsRedraw = true;
2069 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2070 }
2071 setMDPCompLayerFlags(ctx, list);
2072 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302073#ifdef DYNAMIC_FPS
2074 setDynRefreshRate(ctx, list);
2075#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002076 ret = -1;
2077 return ret;
2078 } else {
2079 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2080 }
2081
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302082 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2083 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2084
2085 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2086 mCurrentFrame.needsRedraw = false;
2087 setMDPCompLayerFlags(ctx, list);
2088 mCachedFrame.updateCounts(mCurrentFrame);
2089#ifdef DYNAMIC_FPS
2090 setDynRefreshRate(ctx, list);
2091#endif
2092 return -1;
2093
2094 }
2095
Saurabh Shahb39f8152013-08-22 10:21:44 -07002096 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002097 if(isFrameDoable(ctx)) {
2098 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002099 // if AIV Video mode is enabled, drop all non AIV layers from the
2100 // external display list.
2101 if(ctx->listStats[mDpy].mAIVVideoMode) {
2102 dropNonAIVLayers(ctx, list);
2103 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002104
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002105 // if tryFullFrame fails, try to push all video and secure RGB layers
2106 // to MDP for composition.
2107 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002108 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302109 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002110 setMDPCompLayerFlags(ctx, list);
2111 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002112 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002113 reset(ctx);
2114 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2115 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002116 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002117 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2118 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002119 }
2120 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302121 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2122 enablePartialUpdateForMDP3) {
2123 generateROI(ctx, list);
2124 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2125 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2126 }
2127 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002128 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2129 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002130 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002131 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002132
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002133 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002134 ALOGD("GEOMETRY change: %d",
2135 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002136 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002137 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002138 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002139 }
2140
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002141#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302142 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002143#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002144 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002145
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002146 mCachedFrame.cacheAll(list);
2147 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002148 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002149}
2150
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002151bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302152
2153 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302154 int mdpIndex = mCurrentFrame.layerToMDP[index];
2155 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2156 info.pipeInfo = new MdpYUVPipeInfo;
2157 info.rot = NULL;
2158 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302159
2160 pipe_info.lIndex = ovutils::OV_INVALID;
2161 pipe_info.rIndex = ovutils::OV_INVALID;
2162
Saurabh Shahc62f3982014-03-05 14:28:26 -08002163 Overlay::PipeSpecs pipeSpecs;
2164 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2165 pipeSpecs.needsScaling = true;
2166 pipeSpecs.dpy = mDpy;
2167 pipeSpecs.fb = false;
2168
2169 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302170 if(pipe_info.lIndex == ovutils::OV_INVALID){
2171 bRet = false;
2172 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2173 __FUNCTION__);
2174 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002175 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302176 if(pipe_info.rIndex == ovutils::OV_INVALID){
2177 bRet = false;
2178 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2179 __FUNCTION__);
2180 }
2181 return bRet;
2182}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002183
2184int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2185 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002186 if (ctx->mPtorInfo.isActive()) {
2187 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002188 if (fd < 0) {
2189 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002190 }
2191 }
2192 return fd;
2193}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002194//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002195
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002196void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302197 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002198 //If 4k2k Yuv layer split is possible, and if
2199 //fbz is above 4k2k layer, increment fb zorder by 1
2200 //as we split 4k2k layer and increment zorder for right half
2201 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002202 if(!ctx)
2203 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002204 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302205 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2206 index++) {
2207 if(!mCurrentFrame.isFBComposed[index]) {
2208 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2209 mdpNextZOrder++;
2210 }
2211 mdpNextZOrder++;
2212 hwc_layer_1_t* layer = &list->hwLayers[index];
2213 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302214 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302215 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2216 mCurrentFrame.fbZ += 1;
2217 mdpNextZOrder++;
2218 //As we split 4kx2k yuv layer and program to 2 VG pipes
2219 //(if available) increase mdpcount by 1.
2220 mCurrentFrame.mdpCount++;
2221 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002222 }
2223 }
2224 }
radhakrishnac9a67412013-09-25 17:40:42 +05302225}
2226
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002227/*
2228 * Configures pipe(s) for MDP composition
2229 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002230int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002231 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002232 MdpPipeInfoNonSplit& mdp_info =
2233 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302234 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002235 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002236 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002237
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002238 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2239 __FUNCTION__, layer, zOrder, dest);
2240
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002241 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002242 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002243}
2244
Saurabh Shah88e4d272013-09-03 13:31:29 -07002245bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002246 hwc_display_contents_1_t* list) {
2247 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002248
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002249 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002250
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002251 hwc_layer_1_t* layer = &list->hwLayers[index];
2252 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302253 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002254 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302255 continue;
2256 }
2257 }
2258
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002259 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002260 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002261 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002262 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002263 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002264
Saurabh Shahc62f3982014-03-05 14:28:26 -08002265 Overlay::PipeSpecs pipeSpecs;
2266 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2267 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2268 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2269 (qdutils::MDPVersion::getInstance().is8x26() and
2270 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2271 pipeSpecs.dpy = mDpy;
2272 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002273 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002274
Saurabh Shahc62f3982014-03-05 14:28:26 -08002275 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2276
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002277 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002278 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002279 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002280 }
2281 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002282 return true;
2283}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002284
radhakrishnac9a67412013-09-25 17:40:42 +05302285int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2286 PipeLayerPair& PipeLayerPair) {
2287 MdpYUVPipeInfo& mdp_info =
2288 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2289 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302290 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302291 eDest lDest = mdp_info.lIndex;
2292 eDest rDest = mdp_info.rIndex;
2293
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002294 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302295 lDest, rDest, &PipeLayerPair.rot);
2296}
2297
Saurabh Shah88e4d272013-09-03 13:31:29 -07002298bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002299
Raj Kamal4393eaa2014-06-06 13:45:20 +05302300 if(!isEnabled() or !mModeOn) {
2301 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302302 return true;
2303 }
2304
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002305 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002306 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002307
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002308 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2309 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002310 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002311 if(mCurrentFrame.isFBComposed[i]) continue;
2312
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002313 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002314 private_handle_t *hnd = (private_handle_t *)layer->handle;
2315 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002316 if (!(layer->flags & HWC_COLOR_FILL)) {
2317 ALOGE("%s handle null", __FUNCTION__);
2318 return false;
2319 }
2320 // No PLAY for Color layer
2321 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2322 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002323 }
2324
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002325 int mdpIndex = mCurrentFrame.layerToMDP[i];
2326
Raj Kamal389d6e32014-08-04 14:43:24 +05302327 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302328 {
2329 MdpYUVPipeInfo& pipe_info =
2330 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2331 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2332 ovutils::eDest indexL = pipe_info.lIndex;
2333 ovutils::eDest indexR = pipe_info.rIndex;
2334 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302335 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302336 if(rot) {
2337 rot->queueBuffer(fd, offset);
2338 fd = rot->getDstMemId();
2339 offset = rot->getDstOffset();
2340 }
2341 if(indexL != ovutils::OV_INVALID) {
2342 ovutils::eDest destL = (ovutils::eDest)indexL;
2343 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2344 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2345 if (!ov.queueBuffer(fd, offset, destL)) {
2346 ALOGE("%s: queueBuffer failed for display:%d",
2347 __FUNCTION__, mDpy);
2348 return false;
2349 }
2350 }
2351
2352 if(indexR != ovutils::OV_INVALID) {
2353 ovutils::eDest destR = (ovutils::eDest)indexR;
2354 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2355 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2356 if (!ov.queueBuffer(fd, offset, destR)) {
2357 ALOGE("%s: queueBuffer failed for display:%d",
2358 __FUNCTION__, mDpy);
2359 return false;
2360 }
2361 }
2362 }
2363 else{
2364 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002365 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302366 ovutils::eDest dest = pipe_info.index;
2367 if(dest == ovutils::OV_INVALID) {
2368 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002369 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302370 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002371
radhakrishnac9a67412013-09-25 17:40:42 +05302372 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2373 continue;
2374 }
2375
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002376 int fd = hnd->fd;
2377 uint32_t offset = (uint32_t)hnd->offset;
2378 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2379 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002380 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002381 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002382 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002383 }
2384
radhakrishnac9a67412013-09-25 17:40:42 +05302385 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2386 using pipe: %d", __FUNCTION__, layer,
2387 hnd, dest );
2388
radhakrishnac9a67412013-09-25 17:40:42 +05302389 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2390 if(rot) {
2391 if(!rot->queueBuffer(fd, offset))
2392 return false;
2393 fd = rot->getDstMemId();
2394 offset = rot->getDstOffset();
2395 }
2396
2397 if (!ov.queueBuffer(fd, offset, dest)) {
2398 ALOGE("%s: queueBuffer failed for display:%d ",
2399 __FUNCTION__, mDpy);
2400 return false;
2401 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002402 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002403
2404 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002405 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002406 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002407}
2408
Saurabh Shah88e4d272013-09-03 13:31:29 -07002409//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002410
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002411void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302412 hwc_display_contents_1_t* list){
2413 //if 4kx2k yuv layer is totally present in either in left half
2414 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302415 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302416 if(mCurrentFrame.fbZ >= 0) {
2417 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2418 index++) {
2419 if(!mCurrentFrame.isFBComposed[index]) {
2420 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2421 mdpNextZOrder++;
2422 }
2423 mdpNextZOrder++;
2424 hwc_layer_1_t* layer = &list->hwLayers[index];
2425 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002426 if(isYUVSplitNeeded(hnd) ||
2427 (needs3DComposition(ctx,mDpy) &&
2428 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302429 hwc_rect_t dst = layer->displayFrame;
2430 if((dst.left > lSplit) || (dst.right < lSplit)) {
2431 mCurrentFrame.mdpCount += 1;
2432 }
2433 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2434 mCurrentFrame.fbZ += 1;
2435 mdpNextZOrder++;
2436 }
2437 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002438 }
radhakrishnac9a67412013-09-25 17:40:42 +05302439 }
2440}
2441
Saurabh Shah88e4d272013-09-03 13:31:29 -07002442bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002443 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002444
Saurabh Shahc62f3982014-03-05 14:28:26 -08002445 const int lSplit = getLeftSplit(ctx, mDpy);
2446 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002447 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002448 pipe_info.lIndex = ovutils::OV_INVALID;
2449 pipe_info.rIndex = ovutils::OV_INVALID;
2450
Saurabh Shahc62f3982014-03-05 14:28:26 -08002451 Overlay::PipeSpecs pipeSpecs;
2452 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2453 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2454 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2455 pipeSpecs.dpy = mDpy;
2456 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2457 pipeSpecs.fb = false;
2458
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002459 // Acquire pipe only for the updating half
2460 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2461 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2462
2463 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002464 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002465 if(pipe_info.lIndex == ovutils::OV_INVALID)
2466 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002467 }
2468
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002469 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002470 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2471 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002472 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002473 return false;
2474 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002475
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002476 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002477}
2478
Saurabh Shah88e4d272013-09-03 13:31:29 -07002479bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002480 hwc_display_contents_1_t* list) {
2481 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002482
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002483 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002484
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002485 hwc_layer_1_t* layer = &list->hwLayers[index];
2486 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302487 hwc_rect_t dst = layer->displayFrame;
2488 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302489 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302490 if((dst.left > lSplit)||(dst.right < lSplit)){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002491 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302492 continue;
2493 }
2494 }
2495 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002496 //XXX: Check for forced 2D composition
2497 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2498 if(allocSplitVGPipes(ctx,index))
2499 continue;
2500
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002501 int mdpIndex = mCurrentFrame.layerToMDP[index];
2502 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002503 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002504 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002505 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002506
Saurabh Shahc62f3982014-03-05 14:28:26 -08002507 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2508 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2509 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002510 return false;
2511 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002512 }
2513 return true;
2514}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002515
radhakrishnac9a67412013-09-25 17:40:42 +05302516int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2517 PipeLayerPair& PipeLayerPair) {
2518 const int lSplit = getLeftSplit(ctx, mDpy);
2519 hwc_rect_t dst = layer->displayFrame;
2520 if((dst.left > lSplit)||(dst.right < lSplit)){
2521 MdpYUVPipeInfo& mdp_info =
2522 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2523 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302524 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302525 eDest lDest = mdp_info.lIndex;
2526 eDest rDest = mdp_info.rIndex;
2527
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002528 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302529 lDest, rDest, &PipeLayerPair.rot);
2530 }
2531 else{
2532 return configure(ctx, layer, PipeLayerPair);
2533 }
2534}
2535
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002536/*
2537 * Configures pipe(s) for MDP composition
2538 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002539int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002540 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002541 MdpPipeInfoSplit& mdp_info =
2542 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002543 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302544 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002545 eDest lDest = mdp_info.lIndex;
2546 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002547
2548 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002549 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002550
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002551 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002552 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002553}
2554
Saurabh Shah88e4d272013-09-03 13:31:29 -07002555bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002556
Raj Kamal4393eaa2014-06-06 13:45:20 +05302557 if(!isEnabled() or !mModeOn) {
2558 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302559 return true;
2560 }
2561
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002562 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002563 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002564
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002565 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2566 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002567 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002568 if(mCurrentFrame.isFBComposed[i]) continue;
2569
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002570 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002571 private_handle_t *hnd = (private_handle_t *)layer->handle;
2572 if(!hnd) {
2573 ALOGE("%s handle null", __FUNCTION__);
2574 return false;
2575 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002576
2577 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2578 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002579 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002580
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002581 int mdpIndex = mCurrentFrame.layerToMDP[i];
2582
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002583 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2584 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302585 {
2586 MdpYUVPipeInfo& pipe_info =
2587 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2588 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2589 ovutils::eDest indexL = pipe_info.lIndex;
2590 ovutils::eDest indexR = pipe_info.rIndex;
2591 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302592 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302593 if(rot) {
2594 rot->queueBuffer(fd, offset);
2595 fd = rot->getDstMemId();
2596 offset = rot->getDstOffset();
2597 }
2598 if(indexL != ovutils::OV_INVALID) {
2599 ovutils::eDest destL = (ovutils::eDest)indexL;
2600 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2601 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2602 if (!ov.queueBuffer(fd, offset, destL)) {
2603 ALOGE("%s: queueBuffer failed for display:%d",
2604 __FUNCTION__, mDpy);
2605 return false;
2606 }
2607 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002608
radhakrishnac9a67412013-09-25 17:40:42 +05302609 if(indexR != ovutils::OV_INVALID) {
2610 ovutils::eDest destR = (ovutils::eDest)indexR;
2611 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2612 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2613 if (!ov.queueBuffer(fd, offset, destR)) {
2614 ALOGE("%s: queueBuffer failed for display:%d",
2615 __FUNCTION__, mDpy);
2616 return false;
2617 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002618 }
2619 }
radhakrishnac9a67412013-09-25 17:40:42 +05302620 else{
2621 MdpPipeInfoSplit& pipe_info =
2622 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2623 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002624
radhakrishnac9a67412013-09-25 17:40:42 +05302625 ovutils::eDest indexL = pipe_info.lIndex;
2626 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002627
radhakrishnac9a67412013-09-25 17:40:42 +05302628 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002629 uint32_t offset = (uint32_t)hnd->offset;
2630 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2631 if (!mDpy && (index != -1)) {
2632 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2633 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002634 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002635 }
radhakrishnac9a67412013-09-25 17:40:42 +05302636
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002637 if(ctx->mAD->draw(ctx, fd, offset)) {
2638 fd = ctx->mAD->getDstFd();
2639 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002640 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002641
radhakrishnac9a67412013-09-25 17:40:42 +05302642 if(rot) {
2643 rot->queueBuffer(fd, offset);
2644 fd = rot->getDstMemId();
2645 offset = rot->getDstOffset();
2646 }
2647
2648 //************* play left mixer **********
2649 if(indexL != ovutils::OV_INVALID) {
2650 ovutils::eDest destL = (ovutils::eDest)indexL;
2651 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2652 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2653 if (!ov.queueBuffer(fd, offset, destL)) {
2654 ALOGE("%s: queueBuffer failed for left mixer",
2655 __FUNCTION__);
2656 return false;
2657 }
2658 }
2659
2660 //************* play right mixer **********
2661 if(indexR != ovutils::OV_INVALID) {
2662 ovutils::eDest destR = (ovutils::eDest)indexR;
2663 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2664 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2665 if (!ov.queueBuffer(fd, offset, destR)) {
2666 ALOGE("%s: queueBuffer failed for right mixer",
2667 __FUNCTION__);
2668 return false;
2669 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002670 }
2671 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002672
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002673 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2674 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002675
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002676 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002677}
Saurabh Shahab47c692014-02-12 18:45:57 -08002678
2679//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002680
2681bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2682 hwc_display_contents_1_t* list) {
2683 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2684 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2685
2686 for(int i = numAppLayers - 1; i >= 0; i--) {
2687 if(!isValidRect(visibleRect)) {
2688 mCurrentFrame.drop[i] = true;
2689 mCurrentFrame.dropCount++;
2690 continue;
2691 }
2692
2693 const hwc_layer_1_t* layer = &list->hwLayers[i];
2694 hwc_rect_t dstRect = layer->displayFrame;
2695 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2696
2697 if(!isValidRect(res)) {
2698 mCurrentFrame.drop[i] = true;
2699 mCurrentFrame.dropCount++;
2700 } else {
2701 /* Reset frame ROI when any layer which needs scaling also needs ROI
2702 * cropping */
2703 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2704 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2705 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2706 mCurrentFrame.dropCount = 0;
2707 return false;
2708 }
2709
2710 /* deduct any opaque region from visibleRect */
2711 if (layer->blending == HWC_BLENDING_NONE &&
2712 layer->planeAlpha == 0xFF)
2713 visibleRect = deductRect(visibleRect, res);
2714 }
2715 }
2716 return true;
2717}
2718
2719/*
2720 * HW Limitation: ping pong split can always split the ping pong output
2721 * equally across two DSI's. So the ROI programmed should be of equal width
2722 * for both the halves
2723 */
2724void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2725 hwc_display_contents_1_t* list) {
2726 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2727
2728
2729 if(!canPartialUpdate(ctx, list))
2730 return;
2731
2732 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2733 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2734 (int)ctx->dpyAttr[mDpy].yres};
2735
2736 for(int index = 0; index < numAppLayers; index++ ) {
2737 hwc_layer_1_t* layer = &list->hwLayers[index];
2738
2739 // If we have a RGB layer which needs rotation, no partial update
2740 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2741 return;
2742
2743 if ((mCachedFrame.hnd[index] != layer->handle) ||
2744 isYuvBuffer((private_handle_t *)layer->handle)) {
2745 hwc_rect_t dst = layer->displayFrame;
2746 hwc_rect_t updatingRect = dst;
2747
2748#ifdef QCOM_BSP
2749 if(!needsScaling(layer) && !layer->transform)
2750 {
2751 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2752 int x_off = dst.left - src.left;
2753 int y_off = dst.top - src.top;
2754 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2755 }
2756#endif
2757
2758 roi = getUnion(roi, updatingRect);
2759 }
2760 }
2761
2762 /* No layer is updating. Still SF wants a refresh.*/
2763 if(!isValidRect(roi))
2764 return;
2765
2766 roi = expandROIFromMidPoint(roi, fullFrame);
2767
2768 hwc_rect lFrame = fullFrame;
2769 lFrame.right /= 2;
2770 hwc_rect lRoi = getIntersection(roi, lFrame);
2771
2772 // Align ROI coordinates to panel restrictions
2773 lRoi = getSanitizeROI(lRoi, lFrame);
2774
2775 hwc_rect rFrame = fullFrame;
2776 rFrame.left = lFrame.right;
2777 hwc_rect rRoi = getIntersection(roi, rFrame);
2778
2779 // Align ROI coordinates to panel restrictions
2780 rRoi = getSanitizeROI(rRoi, rFrame);
2781
2782 roi = getUnion(lRoi, rRoi);
2783
2784 ctx->listStats[mDpy].lRoi = roi;
2785 if(!validateAndApplyROI(ctx, list))
2786 resetROI(ctx, mDpy);
2787
2788 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2789 __FUNCTION__,
2790 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2791 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2792 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2793 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2794}
2795
Saurabh Shahab47c692014-02-12 18:45:57 -08002796bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002797 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002798 private_handle_t *hnd = (private_handle_t *)layer->handle;
2799 hwc_rect_t dst = layer->displayFrame;
2800 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2801 pipe_info.lIndex = ovutils::OV_INVALID;
2802 pipe_info.rIndex = ovutils::OV_INVALID;
2803
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002804 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2805 trimAgainstROI(ctx,crop, dst);
2806
Saurabh Shahab47c692014-02-12 18:45:57 -08002807 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2808 //should have a higher priority than the right one. Pipe priorities are
2809 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002810
Saurabh Shahc62f3982014-03-05 14:28:26 -08002811 Overlay::PipeSpecs pipeSpecs;
2812 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2813 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2814 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2815 pipeSpecs.dpy = mDpy;
2816 pipeSpecs.fb = false;
2817
Saurabh Shahab47c692014-02-12 18:45:57 -08002818 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002819 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002820 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002821 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002822 }
2823
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002824 /* Use 2 pipes IF
2825 a) Layer's crop width is > 2048 or
2826 b) Layer's dest width > 2048 or
2827 c) On primary, driver has indicated with caps to split always. This is
2828 based on an empirically derived value of panel height. Applied only
2829 if the layer's width is > mixer's width
2830 */
2831
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302832 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002833 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302834 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002835 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2836 const uint32_t dstWidth = dst.right - dst.left;
2837 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002838 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002839 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002840 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002841 crop.bottom - crop.top;
2842 //Approximation to actual clock, ignoring the common factors in pipe and
2843 //mixer cases like line_time
2844 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2845 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002846
Saurabh Shah05f4e222015-02-05 14:36:22 -08002847 const uint32_t downscale = getRotDownscale(ctx, layer);
2848 if(downscale) {
2849 cropWidth /= downscale;
2850 cropHeight /= downscale;
2851 }
2852
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002853 if(dstWidth > mdpHw.getMaxPipeWidth() or
2854 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002855 (primarySplitAlways and
2856 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002857 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002858 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002859 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002860 }
2861
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002862 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2863 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002864 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002865 }
2866 }
2867
2868 return true;
2869}
2870
Saurabh Shahab47c692014-02-12 18:45:57 -08002871int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2872 PipeLayerPair& PipeLayerPair) {
2873 private_handle_t *hnd = (private_handle_t *)layer->handle;
2874 if(!hnd) {
2875 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2876 return -1;
2877 }
2878 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2879 MdpPipeInfoSplit& mdp_info =
2880 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2881 Rotator **rot = &PipeLayerPair.rot;
2882 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002883 eDest lDest = mdp_info.lIndex;
2884 eDest rDest = mdp_info.rIndex;
2885 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2886 hwc_rect_t dst = layer->displayFrame;
2887 int transform = layer->transform;
2888 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002889 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002890 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002891 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002892 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08002893
2894 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2895 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2896
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002897 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2898 /* MDP driver crops layer coordinates against ROI in Non-Split
2899 * and Split MDP comp. But HWC needs to crop them for source split.
2900 * Reason: 1) Source split is efficient only when the final effective
2901 * load is distributed evenly across mixers.
2902 * 2) We have to know the effective width of the layer that
2903 * the ROI needs to find the no. of pipes the layer needs.
2904 */
2905 trimAgainstROI(ctx, crop, dst);
2906 }
2907
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002908 if(needs3DComposition(ctx, mDpy) &&
2909 get3DFormat(hnd) != HAL_NO_3D){
2910 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
2911 rDest, &PipeLayerPair.rot);
2912 }
2913
Saurabh Shahab47c692014-02-12 18:45:57 -08002914 // Handle R/B swap
2915 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2916 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2917 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2918 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2919 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2920 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002921 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002922 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2923 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002924 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002925 /* Calculate the external display position based on MDP downscale,
2926 ActionSafe, and extorientation features. */
2927 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002928
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002929 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002930 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002931
2932 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2933 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002934 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002935 }
2936
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002937 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002938 (*rot) = ctx->mRotMgr->getNext();
2939 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002940 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002941 //If the video is using a single pipe, enable BWC
2942 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002943 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2944 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002945 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002946 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002947 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002948 ALOGE("%s: configRotator failed!", __FUNCTION__);
2949 return -1;
2950 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002951 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002952 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002953 }
2954
2955 //If 2 pipes being used, divide layer into half, crop and dst
2956 hwc_rect_t cropL = crop;
2957 hwc_rect_t cropR = crop;
2958 hwc_rect_t dstL = dst;
2959 hwc_rect_t dstR = dst;
2960 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2961 cropL.right = (crop.right + crop.left) / 2;
2962 cropR.left = cropL.right;
2963 sanitizeSourceCrop(cropL, cropR, hnd);
2964
Saurabh Shahb729b192014-08-15 18:04:24 -07002965 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002966 //Swap crops on H flip since 2 pipes are being used
2967 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2968 hwc_rect_t tmp = cropL;
2969 cropL = cropR;
2970 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002971 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002972 }
2973
Saurabh Shahb729b192014-08-15 18:04:24 -07002974 //cropSwap trick: If the src and dst widths are both odd, let us say
2975 //2507, then splitting both into half would cause left width to be 1253
2976 //and right 1254. If crop is swapped because of H flip, this will cause
2977 //left crop width to be 1254, whereas left dst width remains 1253, thus
2978 //inducing a scaling that is unaccounted for. To overcome that we add 1
2979 //to the dst width if there is a cropSwap. So if the original width was
2980 //2507, the left dst width will be 1254. Even if the original width was
2981 //even for ex: 2508, the left dst width will still remain 1254.
2982 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002983 dstR.left = dstL.right;
2984 }
2985
2986 //For the mdp, since either we are pre-rotating or MDP does flips
2987 orient = OVERLAY_TRANSFORM_0;
2988 transform = 0;
2989
2990 //configure left pipe
2991 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002992 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002993 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2994 (ovutils::eBlending) getBlending(layer->blending));
2995
2996 if(configMdp(ctx->mOverlay, pargL, orient,
2997 cropL, dstL, metadata, lDest) < 0) {
2998 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2999 return -1;
3000 }
3001 }
3002
3003 //configure right pipe
3004 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003005 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003006 static_cast<eRotFlags>(rotFlags),
3007 layer->planeAlpha,
3008 (ovutils::eBlending) getBlending(layer->blending));
3009 if(configMdp(ctx->mOverlay, pargR, orient,
3010 cropR, dstR, metadata, rDest) < 0) {
3011 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3012 return -1;
3013 }
3014 }
3015
3016 return 0;
3017}
3018
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003019bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3020 Locker::Autolock _l(ctx->mDrawLock);
3021 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3022 char path[MAX_SYSFS_FILE_PATH];
3023 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3024 int fd = open(path, O_RDONLY);
3025 if(fd < 0) {
3026 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3027 return -1;
3028 }
3029 char value[4];
3030 ssize_t size_read = read(fd, value, sizeof(value)-1);
3031 if(size_read <= 0) {
3032 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3033 close(fd);
3034 return -1;
3035 }
3036 close(fd);
3037 value[size_read] = '\0';
3038 return atoi(value);
3039}
3040
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003041int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3042 Locker::Autolock _l(ctx->mDrawLock);
3043 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3044 char path[MAX_SYSFS_FILE_PATH];
3045 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3046 int fd = open(path, O_WRONLY);
3047 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003048 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003049 return -1;
3050 }
3051 char value[4];
3052 snprintf(value, sizeof(value), "%d", (int)enable);
3053 ssize_t ret = write(fd, value, strlen(value));
3054 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003055 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003056 close(fd);
3057 return -1;
3058 }
3059 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003060 return 0;
3061}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003062
3063bool MDPComp::loadPerfLib() {
3064 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3065 bool success = false;
3066 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3067 ALOGE("vendor library not set in ro.vendor.extension_library");
3068 return false;
3069 }
3070
3071 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3072 if(sLibPerfHint) {
3073 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3074 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3075 if (!sPerfLockAcquire || !sPerfLockRelease) {
3076 ALOGE("Failed to load symbols for perfLock");
3077 dlclose(sLibPerfHint);
3078 sLibPerfHint = NULL;
3079 return false;
3080 }
3081 success = true;
3082 ALOGI("Successfully Loaded perf hint API's");
3083 } else {
3084 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3085 }
3086 return success;
3087}
3088
3089void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3090 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3091 return;
3092 }
3093 static int count = sPerfHintWindow;
3094 static int perflockFlag = 0;
3095
3096 /* Send hint to mpctl when single layer is updated
3097 * for a successful number of windows. Hint release
3098 * happens immediately upon multiple layer update.
3099 */
3100 if (onlyVideosUpdating(ctx, list)) {
3101 if(count) {
3102 count--;
3103 }
3104 } else {
3105 if (perflockFlag) {
3106 perflockFlag = 0;
3107 sPerfLockRelease(sPerfLockHandle);
3108 }
3109 count = sPerfHintWindow;
3110 }
3111 if (count == 0 && !perflockFlag) {
3112 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3113 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3114 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003115 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003116 perflockFlag = 1;
3117 }
3118 }
3119}
3120
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003121}; //namespace
3122