blob: 5572cc403c04add26a6b3762f5f6270c3d2fb608 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080022#include <dlfcn.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070023#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070030#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080031
Saurabh Shah85234ec2013-04-12 17:09:00 -070032using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070033using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080034using namespace overlay::utils;
35namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037namespace qhwc {
38
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080039//==============MDPComp========================================================
40
Saurabh Shah59562ff2014-09-30 16:13:12 -070041IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sIdleFallBack = false;
43bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070047int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080050int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053051bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070052bool MDPComp::sIsPartialUpdateActive = true;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080053void *MDPComp::sLibPerfHint = NULL;
54int MDPComp::sPerfLockHandle = 0;
55int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
56int (*MDPComp::sPerfLockRelease)(int value) = NULL;
57int MDPComp::sPerfHintWindow = -1;
58
Saurabh Shah88e4d272013-09-03 13:31:29 -070059MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070060 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
61 sSrcSplitEnabled = true;
62 return new MDPCompSrcSplit(dpy);
63 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070064 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080065 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070066 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080067}
68
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080069MDPComp::MDPComp(int dpy):mDpy(dpy){};
70
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070071void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080072{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070073 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
74 return;
75
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080076 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070077 (mDpy == 0) ? "\"PRIMARY\"" :
78 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070079 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
80 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080081 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
82 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
83 (mCurrentFrame.needsRedraw? "YES" : "NO"),
84 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070085 if(isDisplaySplit(ctx, mDpy)) {
86 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
87 "Right: [%d, %d, %d, %d] \n",
88 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
89 ctx->listStats[mDpy].lRoi.right,
90 ctx->listStats[mDpy].lRoi.bottom,
91 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
92 ctx->listStats[mDpy].rRoi.right,
93 ctx->listStats[mDpy].rRoi.bottom);
94 } else {
95 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
96 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
97 ctx->listStats[mDpy].lRoi.right,
98 ctx->listStats[mDpy].lRoi.bottom);
99 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800100 dumpsys_log(buf," --------------------------------------------- \n");
101 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
102 dumpsys_log(buf," --------------------------------------------- \n");
103 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
104 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
105 index,
106 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700107 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800108 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700109 (mCurrentFrame.drop[index] ? "DROP" :
110 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800111 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
112 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
113 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114}
115
116bool MDPComp::init(hwc_context_t *ctx) {
117
118 if(!ctx) {
119 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
120 return false;
121 }
122
Saurabh Shah59562ff2014-09-30 16:13:12 -0700123 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800124
125 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530126 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
127 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800128 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
129 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800130 sEnabled = true;
131 }
132
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700133 sEnableMixedMode = true;
134 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
135 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
136 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
137 sEnableMixedMode = false;
138 }
139
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700140 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
141
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800142 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700143 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700144 int val = atoi(property);
145 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700146 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800147 }
148
Saurabh Shahacec8e42014-11-25 11:07:04 -0800149 /* Maximum layers allowed to use MDP on secondary panels. If property
150 * doesn't exist, default to 1. Using the property it can be set to 0 or
151 * more.
152 */
153 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
154 int val = atoi(property);
155 sMaxSecLayers = (val >= 0) ? val : 1;
156 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
157 }
158
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400159 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700160 sIdleInvalidator = IdleInvalidator::getInstance();
161 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
162 delete sIdleInvalidator;
163 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400164 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800165 }
radhakrishnac9a67412013-09-25 17:40:42 +0530166
Saurabh Shah7c727642014-06-02 15:47:14 -0700167 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700168 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700169 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
170 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
171 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530172 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530173 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700174
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530175 bool defaultPTOR = false;
176 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
177 //8x16 and 8x39 targets by default
178 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
179 (qdutils::MDPVersion::getInstance().is8x16() ||
180 qdutils::MDPVersion::getInstance().is8x39())) {
181 defaultPTOR = true;
182 }
183
184 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
185 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700186 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
187 HWC_DISPLAY_PRIMARY);
188 }
189
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530190 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
191 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
192 enablePartialUpdateForMDP3 = true;
193 }
194
195 if(!enablePartialUpdateForMDP3 &&
196 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
197 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
198 enablePartialUpdateForMDP3 = true;
199 }
200
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800201 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
202
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800203 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
204 int val = atoi(property);
205 if(val > 0 && loadPerfLib()) {
206 sPerfHintWindow = val;
207 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
208 }
209 }
210
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700211 return true;
212}
213
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800214void MDPComp::reset(hwc_context_t *ctx) {
215 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700216 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800217 ctx->mOverlay->clear(mDpy);
218 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700219}
220
Raj Kamal4393eaa2014-06-06 13:45:20 +0530221void MDPComp::reset() {
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530222 mPrevModeOn = mModeOn;
Raj Kamal4393eaa2014-06-06 13:45:20 +0530223 mModeOn = false;
224}
225
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700226void MDPComp::timeout_handler(void *udata) {
227 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530228 bool handleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700229
230 if(!ctx) {
231 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
232 return;
233 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530234
235 ctx->mDrawLock.lock();
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530236
237 /* Handle timeout event only if the previous composition
238 on any display is MDP or MIXED*/
239 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
240 if(ctx->mMDPComp[i])
241 handleTimeout =
242 ctx->mMDPComp[i]->isMDPComp() || handleTimeout;
243 }
244
245 if(!handleTimeout) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800246 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530247 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800248 return;
249 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700250 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700251 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530252 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700253 return;
254 }
255 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530256 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700257 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700258 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700259}
260
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700261void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
262 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800263 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700264 if(value > maxSupported) {
265 ALOGW("%s: Input exceeds max value supported. Setting to"
266 "max value: %d", __FUNCTION__, maxSupported);
267 }
268 sMaxPipesPerMixer = min(value, maxSupported);
269}
270
Saurabh Shah59562ff2014-09-30 16:13:12 -0700271void MDPComp::setIdleTimeout(const uint32_t& timeout) {
272 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
273
274 if(sIdleInvalidator) {
275 if(timeout <= ONE_REFRESH_PERIOD_MS) {
276 //If the specified timeout is < 1 draw cycle worth, "virtually"
277 //disable idle timeout. The ideal way for clients to disable
278 //timeout is to set it to 0
279 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
280 ALOGI("Disabled idle timeout");
281 return;
282 }
283 sIdleInvalidator->setIdleTimeout(timeout);
284 ALOGI("Idle timeout set to %u", timeout);
285 } else {
286 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
287 }
288}
289
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800290void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800291 hwc_display_contents_1_t* list) {
292 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800293
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800294 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800295 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 if(!mCurrentFrame.isFBComposed[index]) {
297 layerProp[index].mFlags |= HWC_MDPCOMP;
298 layer->compositionType = HWC_OVERLAY;
299 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700301 /* Drop the layer when its already present in FB OR when it lies
302 * outside frame's ROI */
303 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800304 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700305 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800306 }
307 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700308}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500309
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800310void MDPComp::setRedraw(hwc_context_t *ctx,
311 hwc_display_contents_1_t* list) {
312 mCurrentFrame.needsRedraw = false;
313 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
314 (list->flags & HWC_GEOMETRY_CHANGED) ||
315 isSkipPresent(ctx, mDpy)) {
316 mCurrentFrame.needsRedraw = true;
317 }
318}
319
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800320MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700321 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700322 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800323}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800324
Saurabh Shahaa236822013-04-24 18:07:26 -0700325void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700326 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800327 if(mdpToLayer[i].pipeInfo) {
328 delete mdpToLayer[i].pipeInfo;
329 mdpToLayer[i].pipeInfo = NULL;
330 //We dont own the rotator
331 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800332 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800333 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800334
335 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
336 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700337 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800338
Saurabh Shahaa236822013-04-24 18:07:26 -0700339 layerCount = numLayers;
340 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800341 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700342 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800343 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800344}
345
Saurabh Shahaa236822013-04-24 18:07:26 -0700346void MDPComp::FrameInfo::map() {
347 // populate layer and MDP maps
348 int mdpIdx = 0;
349 for(int idx = 0; idx < layerCount; idx++) {
350 if(!isFBComposed[idx]) {
351 mdpToLayer[mdpIdx].listIndex = idx;
352 layerToMDP[idx] = mdpIdx++;
353 }
354 }
355}
356
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357MDPComp::LayerCache::LayerCache() {
358 reset();
359}
360
361void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700362 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530363 memset(&isFBComposed, true, sizeof(isFBComposed));
364 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800365 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700366}
367
368void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530369 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700370 for(int i = 0; i < numAppLayers; i++) {
371 hnd[i] = list->hwLayers[i].handle;
372 }
373}
374
375void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700376 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530377 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
378 memcpy(&drop, &curFrame.drop, sizeof(drop));
379}
380
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800381bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
382 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530383 if(layerCount != curFrame.layerCount)
384 return false;
385 for(int i = 0; i < curFrame.layerCount; i++) {
386 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
387 (curFrame.drop[i] != drop[i])) {
388 return false;
389 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800390 if(curFrame.isFBComposed[i] &&
391 (hnd[i] != list->hwLayers[i].handle)){
392 return false;
393 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530394 }
395 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800396}
397
Raj Kamalfdfdddf2015-03-16 21:59:25 +0530398bool MDPComp::LayerCache::isSameFrame(hwc_context_t *ctx, int dpy,
399 hwc_display_contents_1_t* list) {
400
401 if(layerCount != ctx->listStats[dpy].numAppLayers)
402 return false;
403
404 if((list->flags & HWC_GEOMETRY_CHANGED) ||
405 isSkipPresent(ctx, dpy)) {
406 return false;
407 }
408
409 for(int i = 0; i < layerCount; i++) {
410 if(hnd[i] != list->hwLayers[i].handle)
411 return false;
412 }
413
414 return true;
415}
416
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700417bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
418 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800419 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530420 (not isValidDimension(ctx,layer)) ||
421 isSkipLayer(layer)) {
422 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700423 return false;
424 }
425 return true;
426}
427
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530428bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800429 private_handle_t *hnd = (private_handle_t *)layer->handle;
430
431 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700432 if (layer->flags & HWC_COLOR_FILL) {
433 // Color layer
434 return true;
435 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700436 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800437 return false;
438 }
439
Naseer Ahmede850a802013-09-06 13:12:52 -0400440 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400441 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400442 return false;
443
Saurabh Shah62e1d732013-09-17 10:44:05 -0700444 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700445 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700446 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700447 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
448 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700449 int dst_w = dst.right - dst.left;
450 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800451 float w_scale = ((float)crop_w / (float)dst_w);
452 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530453 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700454
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800455 /* Workaround for MDP HW limitation in DSI command mode panels where
456 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
457 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530458 * There also is a HW limilation in MDP, minimum block size is 2x2
459 * Fallback to GPU if height is less than 2.
460 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700461 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800462 return false;
463
Ramkumar Radhakrishnan1a763e92015-03-19 16:46:46 -0700464 /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
465 * those cases
466 */
467 if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
468 return false;
469 }
470
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800471 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530472 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800473 const float w_dscale = w_scale;
474 const float h_dscale = h_scale;
475
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800476 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700477
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530478 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700479 /* On targets that doesnt support Decimation (eg.,8x26)
480 * maximum downscale support is overlay pipe downscale.
481 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800482 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530483 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700484 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800485 return false;
486 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700487 // Decimation on macrotile format layers is not supported.
488 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530489 /* Bail out if
490 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700491 * 2. exceeds maximum downscale limit
492 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800493 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530494 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700495 w_dscale > maxMDPDownscale ||
496 h_dscale > maxMDPDownscale) {
497 return false;
498 }
499 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800500 return false;
501 }
502 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700503 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700504 return false;
505 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700506 }
507
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800508 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530509 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800510 const float w_uscale = 1.0f / w_scale;
511 const float h_uscale = 1.0f / h_scale;
512
513 if(w_uscale > upscale || h_uscale > upscale)
514 return false;
515 }
516
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800517 return true;
518}
519
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800520bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700521 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800522
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800523 if(!isEnabled()) {
524 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700525 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530526 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530527 qdutils::MDPVersion::getInstance().is8x16() ||
528 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800529 ctx->mVideoTransFlag &&
530 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700531 //1 Padding round to shift pipes across mixers
532 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
533 __FUNCTION__);
534 ret = false;
Raj Kamalc0d34242015-03-17 20:53:14 +0530535 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
536 qdutils::MDPVersion::getInstance().is8x16() ||
537 qdutils::MDPVersion::getInstance().is8x39()) &&
538 !mDpy && isSecondaryAnimating(ctx) &&
539 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
540 ALOGD_IF(isDebug(),"%s: Display animation in progress",
541 __FUNCTION__);
542 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700543 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
544 /* TODO: freeing up all the resources only for the targets having total
545 number of pipes < 8. Need to analyze number of VIG pipes used
546 for primary in previous draw cycle and accordingly decide
547 whether to fall back to full GPU comp or video only comp
548 */
549 if(isSecondaryConfiguring(ctx)) {
550 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
551 __FUNCTION__);
552 ret = false;
553 } else if(ctx->isPaddingRound) {
554 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
555 __FUNCTION__,mDpy);
556 ret = false;
557 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800558 } else if (ctx->isDMAStateChanging) {
559 // Bail out if a padding round has been invoked in order to switch DMA
560 // state to block mode. We need this to cater for the case when a layer
561 // requires rotation in the current frame.
562 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
563 __FUNCTION__);
564 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700565 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800566
Saurabh Shahaa236822013-04-24 18:07:26 -0700567 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800568}
569
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800570void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
571 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800572 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800573 dst = getIntersection(dst, roi);
574 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575}
576
577/* 1) Identify layers that are not visible or lying outside the updating ROI and
578 * drop them from composition.
579 * 2) If we have a scaling layer which needs cropping against generated
580 * ROI, reset ROI to full resolution. */
581bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
582 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700583 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800584 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800585
586 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800587 if(!isValidRect(visibleRect)) {
588 mCurrentFrame.drop[i] = true;
589 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800590 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800591 }
592
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700593 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700594 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800595 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700596
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700597 if(!isValidRect(res)) {
598 mCurrentFrame.drop[i] = true;
599 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800600 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700601 /* Reset frame ROI when any layer which needs scaling also needs ROI
602 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800603 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800604 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700605 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
606 mCurrentFrame.dropCount = 0;
607 return false;
608 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800609
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800610 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530611 if (layer->blending == HWC_BLENDING_NONE &&
612 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800613 visibleRect = deductRect(visibleRect, res);
614 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700615 }
616 return true;
617}
618
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800619/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
620 * are updating. If DirtyRegion is applicable, calculate it by accounting all
621 * the changing layer's dirtyRegion. */
622void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
623 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700624 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800625 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700626 return;
627
628 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800629 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
630 (int)ctx->dpyAttr[mDpy].yres};
631
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700632 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800633 hwc_layer_1_t* layer = &list->hwLayers[index];
634 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800635 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700636 hwc_rect_t dst = layer->displayFrame;
637 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800638
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800639#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530640 if(!needsScaling(layer) && !layer->transform &&
641 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700642 {
643 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
644 int x_off = dst.left - src.left;
645 int y_off = dst.top - src.top;
646 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
647 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800648#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800649
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800650 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700651 }
652 }
653
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800654 /* No layer is updating. Still SF wants a refresh.*/
655 if(!isValidRect(roi))
656 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800657
658 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800659 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800660
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800661 ctx->listStats[mDpy].lRoi = roi;
662 if(!validateAndApplyROI(ctx, list))
663 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700664
665 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800666 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
667 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
668}
669
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800670void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
671 hwc_rect &dst) {
672 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
673 ctx->listStats[mDpy].rRoi);
674 hwc_rect tmpDst = getIntersection(dst, roi);
675 if(!isSameRect(dst, tmpDst)) {
676 crop.left = crop.left + (tmpDst.left - dst.left);
677 crop.top = crop.top + (tmpDst.top - dst.top);
678 crop.right = crop.left + (tmpDst.right - tmpDst.left);
679 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
680 dst = tmpDst;
681 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800682}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800683
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800684/* 1) Identify layers that are not visible or lying outside BOTH the updating
685 * ROI's and drop them from composition. If a layer is spanning across both
686 * the halves of the screen but needed by only ROI, the non-contributing
687 * half will not be programmed for MDP.
688 * 2) If we have a scaling layer which needs cropping against generated
689 * ROI, reset ROI to full resolution. */
690bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
691 hwc_display_contents_1_t* list) {
692
693 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
694
695 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
696 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
697
698 for(int i = numAppLayers - 1; i >= 0; i--){
699 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
700 {
701 mCurrentFrame.drop[i] = true;
702 mCurrentFrame.dropCount++;
703 continue;
704 }
705
706 const hwc_layer_1_t* layer = &list->hwLayers[i];
707 hwc_rect_t dstRect = layer->displayFrame;
708
709 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
710 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
711 hwc_rect_t res = getUnion(l_res, r_res);
712
713 if(!isValidRect(l_res) && !isValidRect(r_res)) {
714 mCurrentFrame.drop[i] = true;
715 mCurrentFrame.dropCount++;
716 } else {
717 /* Reset frame ROI when any layer which needs scaling also needs ROI
718 * cropping */
719 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
720 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
721 mCurrentFrame.dropCount = 0;
722 return false;
723 }
724
radhakrishna4efbdd62014-11-03 13:19:27 +0530725 if (layer->blending == HWC_BLENDING_NONE &&
726 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800727 visibleRectL = deductRect(visibleRectL, l_res);
728 visibleRectR = deductRect(visibleRectR, r_res);
729 }
730 }
731 }
732 return true;
733}
734/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
735 * are updating. If DirtyRegion is applicable, calculate it by accounting all
736 * the changing layer's dirtyRegion. */
737void MDPCompSplit::generateROI(hwc_context_t *ctx,
738 hwc_display_contents_1_t* list) {
739 if(!canPartialUpdate(ctx, list))
740 return;
741
742 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
743 int lSplit = getLeftSplit(ctx, mDpy);
744
745 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
746 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
747
748 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
749 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
750
751 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
752 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
753
754 for(int index = 0; index < numAppLayers; index++ ) {
755 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800756 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800757 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800758 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700759 hwc_rect_t dst = layer->displayFrame;
760 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800761
762#ifdef QCOM_BSP
763 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700764 {
765 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
766 int x_off = dst.left - src.left;
767 int y_off = dst.top - src.top;
768 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
769 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800770#endif
771
772 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
773 if(isValidRect(l_dst))
774 l_roi = getUnion(l_roi, l_dst);
775
776 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
777 if(isValidRect(r_dst))
778 r_roi = getUnion(r_roi, r_dst);
779 }
780 }
781
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700782 /* For panels that cannot accept commands in both the interfaces, we cannot
783 * send two ROI's (for each half). We merge them into single ROI and split
784 * them across lSplit for MDP mixer use. The ROI's will be merged again
785 * finally before udpating the panel in the driver. */
786 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
787 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
788 l_roi = getIntersection(temp_roi, l_frame);
789 r_roi = getIntersection(temp_roi, r_frame);
790 }
791
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800792 /* No layer is updating. Still SF wants a refresh. */
793 if(!isValidRect(l_roi) && !isValidRect(r_roi))
794 return;
795
796 l_roi = getSanitizeROI(l_roi, l_frame);
797 r_roi = getSanitizeROI(r_roi, r_frame);
798
799 ctx->listStats[mDpy].lRoi = l_roi;
800 ctx->listStats[mDpy].rRoi = r_roi;
801
802 if(!validateAndApplyROI(ctx, list))
803 resetROI(ctx, mDpy);
804
805 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
806 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
807 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
808 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
809 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
810 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700811}
812
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800813/* Checks for conditions where all the layers marked for MDP comp cannot be
814 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800815bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800816 hwc_display_contents_1_t* list){
817
Saurabh Shahaa236822013-04-24 18:07:26 -0700818 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800819
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700820 // Fall back to video only composition, if AIV video mode is enabled
821 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700822 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
823 __FUNCTION__, mDpy);
824 return false;
825 }
826
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530827 /* No Idle fall back if secure display or secure RGB layers are present
828 * or if there is only a single layer being composed */
829 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
830 !ctx->listStats[mDpy].secureRGBCount &&
831 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700832 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
833 return false;
834 }
835
Raj Kamalc0d34242015-03-17 20:53:14 +0530836 if(!mDpy && isSecondaryAnimating(ctx) &&
837 (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
838 isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
839 ALOGD_IF(isDebug(),"%s: Display animation in progress",
840 __FUNCTION__);
841 return false;
842 }
843
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700844 // if secondary is configuring or Padding round, fall back to video only
845 // composition and release all assigned non VIG pipes from primary.
846 if(isSecondaryConfiguring(ctx)) {
847 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
848 __FUNCTION__);
849 return false;
850 } else if(ctx->isPaddingRound) {
851 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
852 __FUNCTION__,mDpy);
853 return false;
854 }
855
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500856 // No MDP composition for 3D
857 if(needs3DComposition(ctx, mDpy))
858 return false;
859
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700860 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800861 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700862 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800863 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
864 return false;
865 }
866
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800867 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800868 hwc_layer_1_t* layer = &list->hwLayers[i];
869 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800870
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800871 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700872 if(!canUseRotator(ctx, mDpy)) {
873 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
874 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700875 return false;
876 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800877 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530878
879 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
880 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800881 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700882 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530883 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
884 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
885 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800886 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700887
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700888 if(ctx->mAD->isDoable()) {
889 return false;
890 }
891
Saurabh Shahaa236822013-04-24 18:07:26 -0700892 //If all above hard conditions are met we can do full or partial MDP comp.
893 bool ret = false;
894 if(fullMDPComp(ctx, list)) {
895 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700896 } else if(fullMDPCompWithPTOR(ctx, list)) {
897 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700898 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700899 ret = true;
900 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530901
Saurabh Shahaa236822013-04-24 18:07:26 -0700902 return ret;
903}
904
905bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700906
907 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
908 return false;
909
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700910 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
911 for(int i = 0; i < numAppLayers; i++) {
912 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700913 if(not mCurrentFrame.drop[i] and
914 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700915 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
916 return false;
917 }
918 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800919
Saurabh Shahaa236822013-04-24 18:07:26 -0700920 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700921 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
922 sizeof(mCurrentFrame.isFBComposed));
923 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
924 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700925
Raj Kamal389d6e32014-08-04 14:43:24 +0530926 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800927 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530928 }
929
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800930 if(!postHeuristicsHandling(ctx, list)) {
931 ALOGD_IF(isDebug(), "post heuristic handling failed");
932 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700933 return false;
934 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700935 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
936 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700937 return true;
938}
939
Sushil Chauhandefd3522014-05-13 18:17:12 -0700940/* Full MDP Composition with Peripheral Tiny Overlap Removal.
941 * MDP bandwidth limitations can be avoided, if the overlap region
942 * covered by the smallest layer at a higher z-order, gets composed
943 * by Copybit on a render buffer, which can be queued to MDP.
944 */
945bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
946 hwc_display_contents_1_t* list) {
947
948 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
949 const int stagesForMDP = min(sMaxPipesPerMixer,
950 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
951
952 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700953 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700954 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
955 return false;
956 }
957
958 // Frame level checks
959 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
960 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
961 isSecurePresent(ctx, mDpy)) {
962 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
963 return false;
964 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700965 // MDP comp checks
966 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700967 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700968 if(not isSupportedForMDPComp(ctx, layer)) {
969 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
970 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700971 }
972 }
973
Sushil Chauhandefd3522014-05-13 18:17:12 -0700974 /* We cannot use this composition mode, if:
975 1. A below layer needs scaling.
976 2. Overlap is not peripheral to display.
977 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700978 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700979 */
980
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700981 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
982 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
983 memset(overlapRect, 0, sizeof(overlapRect));
984 int layerPixelCount, minPixelCount = 0;
985 int numPTORLayersFound = 0;
986 for (int i = numAppLayers-1; (i >= 0 &&
987 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700988 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700989 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700990 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700991 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
992 // PTOR layer should be peripheral and cannot have transform
993 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
994 has90Transform(layer)) {
995 continue;
996 }
997 if((3 * (layerPixelCount + minPixelCount)) >
998 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
999 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
1000 continue;
1001 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001002 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001003 for (int j = i-1; j >= 0; j--) {
1004 // Check if the layers below this layer qualifies for PTOR comp
1005 hwc_layer_1_t* layer = &list->hwLayers[j];
1006 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001007 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001008 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001009 if (isValidRect(getIntersection(dispFrame, disFrame))) {
1010 if (has90Transform(layer) || needsScaling(layer)) {
1011 found = false;
1012 break;
1013 }
1014 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001015 }
1016 }
1017 // Store the minLayer Index
1018 if(found) {
1019 minLayerIndex[numPTORLayersFound] = i;
1020 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
1021 minPixelCount += layerPixelCount;
1022 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001023 }
1024 }
1025
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001026 // No overlap layers
1027 if (!numPTORLayersFound)
1028 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001029
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001030 // Store the displayFrame and the sourceCrops of the layers
1031 hwc_rect_t displayFrame[numAppLayers];
1032 hwc_rect_t sourceCrop[numAppLayers];
1033 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001034 hwc_layer_1_t* layer = &list->hwLayers[i];
1035 displayFrame[i] = layer->displayFrame;
1036 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001037 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001038
Prabhanjan Kandula9889a202014-09-04 21:50:35 +05301039 /**
1040 * It's possible that 2 PTOR layers might have overlapping.
1041 * In such case, remove the intersection(again if peripheral)
1042 * from the lower PTOR layer to avoid overlapping.
1043 * If intersection is not on peripheral then compromise
1044 * by reducing number of PTOR layers.
1045 **/
1046 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1047 if(isValidRect(commonRect)) {
1048 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1049 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1050 }
1051
1052 ctx->mPtorInfo.count = numPTORLayersFound;
1053 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1054 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1055 }
1056
1057 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1058 // reset PTOR
1059 ctx->mPtorInfo.count = 0;
1060 if(isValidRect(commonRect)) {
1061 // If PTORs are intersecting restore displayframe of PTOR[1]
1062 // before returning, as we have modified it above.
1063 list->hwLayers[minLayerIndex[1]].displayFrame =
1064 displayFrame[minLayerIndex[1]];
1065 }
1066 return false;
1067 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001068 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1069 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1070
Xu Yangcda012c2014-07-30 21:57:21 +08001071 // Store the blending mode, planeAlpha, and transform of PTOR layers
1072 int32_t blending[numPTORLayersFound];
1073 uint8_t planeAlpha[numPTORLayersFound];
1074 uint32_t transform[numPTORLayersFound];
1075
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001076 for(int j = 0; j < numPTORLayersFound; j++) {
1077 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001078
1079 // Update src crop of PTOR layer
1080 hwc_layer_1_t* layer = &list->hwLayers[index];
1081 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1082 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1083 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1084 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1085
1086 // Store & update w, h, format of PTOR layer
1087 private_handle_t *hnd = (private_handle_t *)layer->handle;
1088 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1089 layerWhf[j] = whf;
1090 hnd->width = renderBuf->width;
1091 hnd->height = renderBuf->height;
1092 hnd->format = renderBuf->format;
1093
Xu Yangcda012c2014-07-30 21:57:21 +08001094 // Store & update blending mode, planeAlpha and transform of PTOR layer
1095 blending[j] = layer->blending;
1096 planeAlpha[j] = layer->planeAlpha;
1097 transform[j] = layer->transform;
1098 layer->blending = HWC_BLENDING_NONE;
1099 layer->planeAlpha = 0xFF;
1100 layer->transform = 0;
1101
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001102 // Remove overlap from crop & displayFrame of below layers
1103 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001104 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001105 if(!isValidRect(getIntersection(layer->displayFrame,
1106 overlapRect[j]))) {
1107 continue;
1108 }
1109 // Update layer attributes
1110 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1111 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301112 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001113 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1114 layer->transform);
1115 layer->sourceCropf.left = (float)srcCrop.left;
1116 layer->sourceCropf.top = (float)srcCrop.top;
1117 layer->sourceCropf.right = (float)srcCrop.right;
1118 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1119 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001120 }
1121
1122 mCurrentFrame.mdpCount = numAppLayers;
1123 mCurrentFrame.fbCount = 0;
1124 mCurrentFrame.fbZ = -1;
1125
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301126 for (int j = 0; j < numAppLayers; j++) {
1127 if(isValidRect(list->hwLayers[j].displayFrame)) {
1128 mCurrentFrame.isFBComposed[j] = false;
1129 } else {
1130 mCurrentFrame.mdpCount--;
1131 mCurrentFrame.drop[j] = true;
1132 }
1133 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001134
1135 bool result = postHeuristicsHandling(ctx, list);
1136
1137 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001138 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001139 hwc_layer_1_t* layer = &list->hwLayers[i];
1140 layer->displayFrame = displayFrame[i];
1141 layer->sourceCropf.left = (float)sourceCrop[i].left;
1142 layer->sourceCropf.top = (float)sourceCrop[i].top;
1143 layer->sourceCropf.right = (float)sourceCrop[i].right;
1144 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1145 }
1146
Xu Yangcda012c2014-07-30 21:57:21 +08001147 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001148 for (int i = 0; i < numPTORLayersFound; i++) {
1149 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001150 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001151 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1152 hnd->width = layerWhf[i].w;
1153 hnd->height = layerWhf[i].h;
1154 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001155 layer->blending = blending[i];
1156 layer->planeAlpha = planeAlpha[i];
1157 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001158 }
1159
Sushil Chauhandefd3522014-05-13 18:17:12 -07001160 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001161 // reset PTOR
1162 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001163 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001164 } else {
1165 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1166 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001167 }
1168
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001169 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1170 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001171 return result;
1172}
1173
Saurabh Shahaa236822013-04-24 18:07:26 -07001174bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1175{
radhakrishnac3198ff2015-03-10 17:10:02 +05301176 if(!sEnableMixedMode || !isAlphaPresentinFB(ctx, mDpy)) {
1177 //Mixed mode is disabled/can't be used. No need to even try caching.
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001178 return false;
1179 }
1180
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001181 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301182 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1183 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001184 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001185 cacheBasedComp(ctx, list);
1186 } else {
1187 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001188 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001189 }
1190
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001191 return ret;
1192}
1193
1194bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1195 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001196 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1197 return false;
1198
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001199 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001200 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001201 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001202
1203 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1204 for(int i = 0; i < numAppLayers; i++) {
1205 if(!mCurrentFrame.isFBComposed[i]) {
1206 hwc_layer_1_t* layer = &list->hwLayers[i];
1207 if(not isSupportedForMDPComp(ctx, layer)) {
1208 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1209 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001210 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001211 return false;
1212 }
1213 }
1214 }
1215
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001216 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001217 /* mark secure RGB layers for MDP comp */
1218 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301219 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001220 if(!ret) {
1221 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001222 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001223 return false;
1224 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001225
1226 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001227
Raj Kamal389d6e32014-08-04 14:43:24 +05301228 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001229 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301230 }
1231
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001232 if(!postHeuristicsHandling(ctx, list)) {
1233 ALOGD_IF(isDebug(), "post heuristic handling failed");
1234 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001235 return false;
1236 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001237 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1238 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001239
Saurabh Shahaa236822013-04-24 18:07:26 -07001240 return true;
1241}
1242
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001243bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001244 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001245 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1246 return false;
1247
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001248 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001249 return false;
1250 }
1251
Saurabh Shahb772ae32013-11-18 15:40:02 -08001252 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001253 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1254 const int stagesForMDP = min(sMaxPipesPerMixer,
1255 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001256
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001257 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1258 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1259 int lastMDPSupportedIndex = numAppLayers;
1260 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001261
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001262 //Find the minimum MDP batch size
1263 for(int i = 0; i < numAppLayers;i++) {
1264 if(mCurrentFrame.drop[i]) {
1265 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001266 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001267 }
1268 hwc_layer_1_t* layer = &list->hwLayers[i];
1269 if(not isSupportedForMDPComp(ctx, layer)) {
1270 lastMDPSupportedIndex = i;
1271 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1272 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001273 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001274 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001275 }
1276
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001277 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1278 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1279 mCurrentFrame.dropCount);
1280
1281 //Start at a point where the fb batch should at least have 2 layers, for
1282 //this mode to be justified.
1283 while(fbBatchSize < 2) {
1284 ++fbBatchSize;
1285 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001286 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001287
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001288 //If there are no layers for MDP, this mode doesnt make sense.
1289 if(mdpBatchSize < 1) {
1290 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1291 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001292 return false;
1293 }
1294
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001295 mCurrentFrame.reset(numAppLayers);
1296
1297 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1298 while(mdpBatchSize > 0) {
1299 //Mark layers for MDP comp
1300 int mdpBatchLeft = mdpBatchSize;
1301 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1302 if(mCurrentFrame.drop[i]) {
1303 continue;
1304 }
1305 mCurrentFrame.isFBComposed[i] = false;
1306 --mdpBatchLeft;
1307 }
1308
1309 mCurrentFrame.fbZ = mdpBatchSize;
1310 mCurrentFrame.fbCount = fbBatchSize;
1311 mCurrentFrame.mdpCount = mdpBatchSize;
1312
1313 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1314 __FUNCTION__, mdpBatchSize, fbBatchSize,
1315 mCurrentFrame.dropCount);
1316
1317 if(postHeuristicsHandling(ctx, list)) {
1318 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001319 __FUNCTION__);
1320 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1321 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001322 return true;
1323 }
1324
1325 reset(ctx);
1326 --mdpBatchSize;
1327 ++fbBatchSize;
1328 }
1329
1330 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001331}
1332
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001333bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301334 if(mDpy or isSecurePresent(ctx, mDpy) or
1335 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001336 return false;
1337 }
1338 return true;
1339}
1340
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001341bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1342 hwc_display_contents_1_t* list){
1343 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1344 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001345 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001346 return false;
1347 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001348 if(ctx->listStats[mDpy].secureUI)
1349 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001350 return true;
1351}
1352
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001353bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1354 hwc_display_contents_1_t* list) {
1355 const bool secureOnly = true;
1356 return videoOnlyComp(ctx, list, not secureOnly) or
1357 videoOnlyComp(ctx, list, secureOnly);
1358}
1359
1360bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001361 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001362 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1363 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301364
Saurabh Shahaa236822013-04-24 18:07:26 -07001365 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301366 if(!isSecurePresent(ctx, mDpy)) {
1367 /* Bail out if we are processing only secured video layers
1368 * and we dont have any */
1369 if(secureOnly) {
1370 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1371 return false;
1372 }
1373 /* No Idle fall back for secure video layers and if there is only
1374 * single layer being composed. */
1375 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1376 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1377 return false;
1378 }
1379 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001380
Saurabh Shahaa236822013-04-24 18:07:26 -07001381 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001382 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001383 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001384 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001385
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001386 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1387 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001388 return false;
1389 }
1390
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001391 if(mCurrentFrame.fbCount)
1392 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001393
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001394 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001395 adjustForSourceSplit(ctx, list);
1396 }
1397
1398 if(!postHeuristicsHandling(ctx, list)) {
1399 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301400 if(errno == ENOBUFS) {
1401 ALOGD_IF(isDebug(), "SMP Allocation failed");
1402 //On SMP allocation failure in video only comp add padding round
1403 ctx->isPaddingRound = true;
1404 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001405 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001406 return false;
1407 }
1408
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001409 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1410 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001411 return true;
1412}
1413
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001414/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1415bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1416 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001417 // Fall back to video only composition, if AIV video mode is enabled
1418 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001419 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1420 __FUNCTION__, mDpy);
1421 return false;
1422 }
1423
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001424 // No MDP composition for 3D
1425 if(needs3DComposition(ctx,mDpy))
1426 return false;
1427
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001428 const bool secureOnly = true;
1429 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1430 mdpOnlyLayersComp(ctx, list, secureOnly);
1431
1432}
1433
1434bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1435 hwc_display_contents_1_t* list, bool secureOnly) {
1436
1437 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1438 return false;
1439
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301440 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1441 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1442 /* Bail out if we are processing only secured video/ui layers
1443 * and we dont have any */
1444 if(secureOnly) {
1445 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1446 return false;
1447 }
1448 /* No Idle fall back for secure video/ui layers and if there is only
1449 * single layer being composed. */
1450 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1451 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1452 return false;
1453 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001454 }
1455
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001456 /* Bail out if we dont have any secure RGB layers */
1457 if (!ctx->listStats[mDpy].secureRGBCount) {
1458 reset(ctx);
1459 return false;
1460 }
1461
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001462 mCurrentFrame.reset(numAppLayers);
1463 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1464
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001465 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001466 /* mark secure RGB layers for MDP comp */
1467 updateSecureRGB(ctx, list);
1468
1469 if(mCurrentFrame.mdpCount == 0) {
1470 reset(ctx);
1471 return false;
1472 }
1473
1474 /* find the maximum batch of layers to be marked for framebuffer */
1475 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1476 if(!ret) {
1477 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1478 reset(ctx);
1479 return false;
1480 }
1481
1482 if(sEnableYUVsplit){
1483 adjustForSourceSplit(ctx, list);
1484 }
1485
1486 if(!postHeuristicsHandling(ctx, list)) {
1487 ALOGD_IF(isDebug(), "post heuristic handling failed");
1488 reset(ctx);
1489 return false;
1490 }
1491
1492 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1493 __FUNCTION__);
1494 return true;
1495}
1496
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001497/* Checks for conditions where YUV layers cannot be bypassed */
1498bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001499 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001500 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001501 return false;
1502 }
1503
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001504 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001505 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1506 return false;
1507 }
1508
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001509 if(isSecuring(ctx, layer)) {
1510 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1511 return false;
1512 }
1513
Saurabh Shah4fdde762013-04-30 18:47:33 -07001514 if(!isValidDimension(ctx, layer)) {
1515 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1516 __FUNCTION__);
1517 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001518 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001519
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001520 if(layer->planeAlpha < 0xFF) {
1521 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1522 in video only mode",
1523 __FUNCTION__);
1524 return false;
1525 }
1526
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001527 return true;
1528}
1529
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001530/* Checks for conditions where Secure RGB layers cannot be bypassed */
1531bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1532 if(isSkipLayer(layer)) {
1533 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1534 __FUNCTION__, mDpy);
1535 return false;
1536 }
1537
1538 if(isSecuring(ctx, layer)) {
1539 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1540 return false;
1541 }
1542
1543 if(not isSupportedForMDPComp(ctx, layer)) {
1544 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1545 __FUNCTION__);
1546 return false;
1547 }
1548 return true;
1549}
1550
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301551/* starts at fromIndex and check for each layer to find
1552 * if it it has overlapping with any Updating layer above it in zorder
1553 * till the end of the batch. returns true if it finds any intersection */
1554bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1555 int fromIndex, int toIndex) {
1556 for(int i = fromIndex; i < toIndex; i++) {
1557 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1558 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1559 return false;
1560 }
1561 }
1562 }
1563 return true;
1564}
1565
1566/* Checks if given layer at targetLayerIndex has any
1567 * intersection with all the updating layers in beween
1568 * fromIndex and toIndex. Returns true if it finds intersectiion */
1569bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1570 int fromIndex, int toIndex, int targetLayerIndex) {
1571 for(int i = fromIndex; i <= toIndex; i++) {
1572 if(!mCurrentFrame.isFBComposed[i]) {
1573 if(areLayersIntersecting(&list->hwLayers[i],
1574 &list->hwLayers[targetLayerIndex])) {
1575 return true;
1576 }
1577 }
1578 }
1579 return false;
1580}
1581
1582int MDPComp::getBatch(hwc_display_contents_1_t* list,
1583 int& maxBatchStart, int& maxBatchEnd,
1584 int& maxBatchCount) {
1585 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301586 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001587 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301588 while (i < mCurrentFrame.layerCount) {
1589 int batchCount = 0;
1590 int batchStart = i;
1591 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001592 /* Adjust batch Z order with the dropped layers so far */
1593 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301594 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301595 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301596 while(i < mCurrentFrame.layerCount) {
1597 if(!mCurrentFrame.isFBComposed[i]) {
1598 if(!batchCount) {
1599 i++;
1600 break;
1601 }
1602 updatingLayersAbove++;
1603 i++;
1604 continue;
1605 } else {
1606 if(mCurrentFrame.drop[i]) {
1607 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001608 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301609 continue;
1610 } else if(updatingLayersAbove <= 0) {
1611 batchCount++;
1612 batchEnd = i;
1613 i++;
1614 continue;
1615 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1616
1617 // We have a valid updating layer already. If layer-i not
1618 // have overlapping with all updating layers in between
1619 // batch-start and i, then we can add layer i to batch.
1620 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1621 batchCount++;
1622 batchEnd = i;
1623 i++;
1624 continue;
1625 } else if(canPushBatchToTop(list, batchStart, i)) {
1626 //If All the non-updating layers with in this batch
1627 //does not have intersection with the updating layers
1628 //above in z-order, then we can safely move the batch to
1629 //higher z-order. Increment fbZ as it is moving up.
1630 if( firstZReverseIndex < 0) {
1631 firstZReverseIndex = i;
1632 }
1633 batchCount++;
1634 batchEnd = i;
1635 fbZ += updatingLayersAbove;
1636 i++;
1637 updatingLayersAbove = 0;
1638 continue;
1639 } else {
1640 //both failed.start the loop again from here.
1641 if(firstZReverseIndex >= 0) {
1642 i = firstZReverseIndex;
1643 }
1644 break;
1645 }
1646 }
1647 }
1648 }
1649 if(batchCount > maxBatchCount) {
1650 maxBatchCount = batchCount;
1651 maxBatchStart = batchStart;
1652 maxBatchEnd = batchEnd;
1653 fbZOrder = fbZ;
1654 }
1655 }
1656 return fbZOrder;
1657}
1658
1659bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1660 hwc_display_contents_1_t* list) {
1661 /* Idea is to keep as many non-updating(cached) layers in FB and
1662 * send rest of them through MDP. This is done in 2 steps.
1663 * 1. Find the maximum contiguous batch of non-updating layers.
1664 * 2. See if we can improve this batch size for caching by adding
1665 * opaque layers around the batch, if they don't have
1666 * any overlapping with the updating layers in between.
1667 * NEVER mark an updating layer for caching.
1668 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001669
1670 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001671 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301673 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001674
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001675 /* Nothing is cached. No batching needed */
1676 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001677 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001678 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001679
1680 /* No MDP comp layers, try to use other comp modes */
1681 if(mCurrentFrame.mdpCount == 0) {
1682 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001683 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001684
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301685 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001686
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301687 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001688 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001689 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001690 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301691 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001692 if(!mCurrentFrame.drop[i]){
1693 //If an unsupported layer is being attempted to
1694 //be pulled out we should fail
1695 if(not isSupportedForMDPComp(ctx, layer)) {
1696 return false;
1697 }
1698 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001699 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001700 }
1701 }
1702
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301703 // update the frame data
1704 mCurrentFrame.fbZ = fbZ;
1705 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001706 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001707 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708
1709 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301710 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001711
1712 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001713}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001714
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001715void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001716 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001717 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001718 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001719
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001720 for(int i = 0; i < numAppLayers; i++) {
1721 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001722 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001723 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001724 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001725 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001726 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727 }
1728 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001729
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001730 frame.fbCount = fbCount;
1731 frame.mdpCount = frame.layerCount - frame.fbCount
1732 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001733
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001734 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1735 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001736}
1737
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001738// drop other non-AIV layers from external display list.
1739void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001740 hwc_display_contents_1_t* list) {
1741 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1742 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001743 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001744 mCurrentFrame.dropCount++;
1745 mCurrentFrame.drop[i] = true;
1746 }
1747 }
1748 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1749 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1750 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1751 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1752 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1753 mCurrentFrame.dropCount);
1754}
1755
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001756void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001757 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001758 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1759 for(int index = 0;index < nYuvCount; index++){
1760 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1761 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1762
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001763 if(mCurrentFrame.drop[nYuvIndex]) {
1764 continue;
1765 }
1766
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001767 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001768 if(!frame.isFBComposed[nYuvIndex]) {
1769 frame.isFBComposed[nYuvIndex] = true;
1770 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001771 }
1772 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001773 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001774 private_handle_t *hnd = (private_handle_t *)layer->handle;
1775 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001776 frame.isFBComposed[nYuvIndex] = false;
1777 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001778 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001779 }
1780 }
1781 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001782
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001783 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1784 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001785}
1786
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001787void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1788 hwc_display_contents_1_t* list) {
1789 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1790 for(int index = 0;index < nSecureRGBCount; index++){
1791 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1792 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1793
1794 if(!isSecureRGBDoable(ctx, layer)) {
1795 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1796 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1797 mCurrentFrame.fbCount++;
1798 }
1799 } else {
1800 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1801 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1802 mCurrentFrame.fbCount--;
1803 }
1804 }
1805 }
1806
1807 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1808 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1809 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1810 mCurrentFrame.fbCount);
1811}
1812
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001813hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1814 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001815 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001816
1817 /* Update only the region of FB needed for composition */
1818 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1819 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1820 hwc_layer_1_t* layer = &list->hwLayers[i];
1821 hwc_rect_t dst = layer->displayFrame;
1822 fbRect = getUnion(fbRect, dst);
1823 }
1824 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001825 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001826 return fbRect;
1827}
1828
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001829bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1830 hwc_display_contents_1_t* list) {
1831
1832 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001833 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001834 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1835 return false;
1836 }
1837
1838 //Limitations checks
1839 if(!hwLimitationsCheck(ctx, list)) {
1840 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1841 return false;
1842 }
1843
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001844 //Configure framebuffer first if applicable
1845 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001846 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001847 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1848 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001849 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1850 __FUNCTION__);
1851 return false;
1852 }
1853 }
1854
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001855 mCurrentFrame.map();
1856
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001857 if(!allocLayerPipes(ctx, list)) {
1858 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001859 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001860 }
1861
1862 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001863 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001864 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001865 int mdpIndex = mCurrentFrame.layerToMDP[index];
1866 hwc_layer_1_t* layer = &list->hwLayers[index];
1867
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301868 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1869 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1870 mdpNextZOrder++;
1871 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001872 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1873 cur_pipe->zOrder = mdpNextZOrder++;
1874
radhakrishnac9a67412013-09-25 17:40:42 +05301875 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301876 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301877 if(configure4k2kYuv(ctx, layer,
1878 mCurrentFrame.mdpToLayer[mdpIndex])
1879 != 0 ){
1880 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1881 for layer %d",__FUNCTION__, index);
1882 return false;
1883 }
1884 else{
1885 mdpNextZOrder++;
1886 }
1887 continue;
1888 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001889 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1890 mdpNextZOrder++;
1891 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001892 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1893 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301894 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001895 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001896 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001897 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001898 }
1899
Saurabh Shaha36be922013-12-16 18:18:39 -08001900 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1901 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1902 ,__FUNCTION__, mDpy);
1903 return false;
1904 }
1905
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001906 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001907 return true;
1908}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001909
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001910bool MDPComp::resourceCheck(hwc_context_t* ctx,
1911 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001912 const bool fbUsed = mCurrentFrame.fbCount;
1913 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1914 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1915 return false;
1916 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001917
1918 //Will benefit cases where a video has non-updating background.
1919 if((mDpy > HWC_DISPLAY_PRIMARY) and
1920 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1921 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1922 return false;
1923 }
1924
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001925 // Init rotCount to number of rotate sessions used by other displays
1926 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1927 // Count the number of rotator sessions required for current display
1928 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1929 if(!mCurrentFrame.isFBComposed[index]) {
1930 hwc_layer_1_t* layer = &list->hwLayers[index];
1931 private_handle_t *hnd = (private_handle_t *)layer->handle;
1932 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1933 rotCount++;
1934 }
1935 }
1936 }
1937 // if number of layers to rotate exceeds max rotator sessions, bail out.
1938 if(rotCount > RotMgr::MAX_ROT_SESS) {
1939 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1940 __FUNCTION__, mDpy);
1941 return false;
1942 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001943 return true;
1944}
1945
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301946bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1947 hwc_display_contents_1_t* list) {
1948
1949 //A-family hw limitation:
1950 //If a layer need alpha scaling, MDP can not support.
1951 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1952 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1953 if(!mCurrentFrame.isFBComposed[i] &&
1954 isAlphaScaled( &list->hwLayers[i])) {
1955 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1956 return false;
1957 }
1958 }
1959 }
1960
1961 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1962 //If multiple layers requires downscaling and also they are overlapping
1963 //fall back to GPU since MDSS can not handle it.
1964 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1965 qdutils::MDPVersion::getInstance().is8x26()) {
1966 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1967 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1968 if(!mCurrentFrame.isFBComposed[i] &&
1969 isDownscaleRequired(botLayer)) {
1970 //if layer-i is marked for MDP and needs downscaling
1971 //check if any MDP layer on top of i & overlaps with layer-i
1972 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1973 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1974 if(!mCurrentFrame.isFBComposed[j] &&
1975 isDownscaleRequired(topLayer)) {
1976 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1977 topLayer->displayFrame);
1978 if(isValidRect(r))
1979 return false;
1980 }
1981 }
1982 }
1983 }
1984 }
1985 return true;
1986}
1987
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001988// Checks only if videos or single layer(RGB) is updating
1989// which is used for setting dynamic fps or perf hint for single
1990// layer video playback
1991bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1992 hwc_display_contents_1_t* list) {
1993 bool support = false;
1994 FrameInfo frame;
1995 frame.reset(mCurrentFrame.layerCount);
1996 memset(&frame.drop, 0, sizeof(frame.drop));
1997 frame.dropCount = 0;
1998 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1999 updateLayerCache(ctx, list, frame);
2000 updateYUV(ctx, list, false /*secure only*/, frame);
2001 // There are only updating YUV layers or there is single RGB
2002 // Layer(Youtube)
2003 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2004 (frame.layerCount == 1)) {
2005 support = true;
2006 }
2007 return support;
2008}
2009
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302010void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2011 //For primary display, set the dynamic refreshrate
2012 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
2013 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302014 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
2015 MDPVersion& mdpHw = MDPVersion::getInstance();
2016 if(sIdleFallBack) {
2017 //Set minimum panel refresh rate during idle timeout
2018 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002019 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302020 //Set the new fresh rate, if there is only one updating YUV layer
2021 //or there is one single RGB layer with this request
2022 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2023 }
2024 setRefreshRate(ctx, mDpy, refreshRate);
2025 }
2026}
2027
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002028int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002029 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002030 char property[PROPERTY_VALUE_MAX];
2031
Raj Kamal4393eaa2014-06-06 13:45:20 +05302032 if(!ctx || !list) {
2033 ALOGE("%s: Invalid context or list",__FUNCTION__);
2034 mCachedFrame.reset();
2035 return -1;
2036 }
2037
2038 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07002039 if(mDpy == HWC_DISPLAY_PRIMARY) {
2040 sSimulationFlags = 0;
2041 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
2042 int currentFlags = atoi(property);
2043 if(currentFlags != sSimulationFlags) {
2044 sSimulationFlags = currentFlags;
2045 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2046 sSimulationFlags, sSimulationFlags);
2047 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002048 }
2049 }
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002050
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302051 //reset old data
2052 mCurrentFrame.reset(numLayers);
2053 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2054 mCurrentFrame.dropCount = 0;
2055
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302056 //Do not cache the information for next draw cycle.
2057 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2058 ALOGI("%s: Unsupported layer count for mdp composition",
2059 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002060 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302061#ifdef DYNAMIC_FPS
2062 setDynRefreshRate(ctx, list);
2063#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002064 return -1;
2065 }
2066
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002067 // Detect the start of animation and fall back to GPU only once to cache
2068 // all the layers in FB and display FB content untill animation completes.
2069 if(ctx->listStats[mDpy].isDisplayAnimating) {
2070 mCurrentFrame.needsRedraw = false;
2071 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2072 mCurrentFrame.needsRedraw = true;
2073 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2074 }
2075 setMDPCompLayerFlags(ctx, list);
2076 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302077#ifdef DYNAMIC_FPS
2078 setDynRefreshRate(ctx, list);
2079#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002080 ret = -1;
2081 return ret;
2082 } else {
2083 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2084 }
2085
Raj Kamalfdfdddf2015-03-16 21:59:25 +05302086 if(!mDpy and !isSecondaryConnected(ctx) and !mPrevModeOn and
2087 mCachedFrame.isSameFrame(ctx,mDpy,list)) {
2088
2089 ALOGD_IF(isDebug(),"%s: Avoid new composition",__FUNCTION__);
2090 mCurrentFrame.needsRedraw = false;
2091 setMDPCompLayerFlags(ctx, list);
2092 mCachedFrame.updateCounts(mCurrentFrame);
2093#ifdef DYNAMIC_FPS
2094 setDynRefreshRate(ctx, list);
2095#endif
2096 return -1;
2097
2098 }
2099
Saurabh Shahb39f8152013-08-22 10:21:44 -07002100 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002101 if(isFrameDoable(ctx)) {
2102 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002103 // if AIV Video mode is enabled, drop all non AIV layers from the
2104 // external display list.
2105 if(ctx->listStats[mDpy].mAIVVideoMode) {
2106 dropNonAIVLayers(ctx, list);
2107 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002108
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002109 // if tryFullFrame fails, try to push all video and secure RGB layers
2110 // to MDP for composition.
2111 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002112 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302113 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002114 setMDPCompLayerFlags(ctx, list);
2115 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002116 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002117 reset(ctx);
2118 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2119 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002120 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002121 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2122 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002123 }
2124 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302125 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2126 enablePartialUpdateForMDP3) {
2127 generateROI(ctx, list);
2128 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2129 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2130 }
2131 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002132 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2133 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002134 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002135 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002136
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002137 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002138 ALOGD("GEOMETRY change: %d",
2139 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002140 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002141 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002142 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002143 }
2144
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002145#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302146 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002147#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002148 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002149
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002150 mCachedFrame.cacheAll(list);
2151 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002152 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002153}
2154
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002155bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302156
2157 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302158 int mdpIndex = mCurrentFrame.layerToMDP[index];
2159 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2160 info.pipeInfo = new MdpYUVPipeInfo;
2161 info.rot = NULL;
2162 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302163
2164 pipe_info.lIndex = ovutils::OV_INVALID;
2165 pipe_info.rIndex = ovutils::OV_INVALID;
2166
Saurabh Shahc62f3982014-03-05 14:28:26 -08002167 Overlay::PipeSpecs pipeSpecs;
2168 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2169 pipeSpecs.needsScaling = true;
2170 pipeSpecs.dpy = mDpy;
2171 pipeSpecs.fb = false;
2172
2173 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302174 if(pipe_info.lIndex == ovutils::OV_INVALID){
2175 bRet = false;
2176 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2177 __FUNCTION__);
2178 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002179 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302180 if(pipe_info.rIndex == ovutils::OV_INVALID){
2181 bRet = false;
2182 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2183 __FUNCTION__);
2184 }
2185 return bRet;
2186}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002187
2188int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2189 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002190 if (ctx->mPtorInfo.isActive()) {
2191 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002192 if (fd < 0) {
2193 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002194 }
2195 }
2196 return fd;
2197}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002198//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002199
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002200void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302201 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002202 //If 4k2k Yuv layer split is possible, and if
2203 //fbz is above 4k2k layer, increment fb zorder by 1
2204 //as we split 4k2k layer and increment zorder for right half
2205 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002206 if(!ctx)
2207 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002208 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302209 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2210 index++) {
2211 if(!mCurrentFrame.isFBComposed[index]) {
2212 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2213 mdpNextZOrder++;
2214 }
2215 mdpNextZOrder++;
2216 hwc_layer_1_t* layer = &list->hwLayers[index];
2217 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302218 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302219 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2220 mCurrentFrame.fbZ += 1;
2221 mdpNextZOrder++;
2222 //As we split 4kx2k yuv layer and program to 2 VG pipes
2223 //(if available) increase mdpcount by 1.
2224 mCurrentFrame.mdpCount++;
2225 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002226 }
2227 }
2228 }
radhakrishnac9a67412013-09-25 17:40:42 +05302229}
2230
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002231/*
2232 * Configures pipe(s) for MDP composition
2233 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002234int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002235 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002236 MdpPipeInfoNonSplit& mdp_info =
2237 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302238 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002239 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002240 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002241
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002242 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2243 __FUNCTION__, layer, zOrder, dest);
2244
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002245 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002246 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002247}
2248
Saurabh Shah88e4d272013-09-03 13:31:29 -07002249bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002250 hwc_display_contents_1_t* list) {
2251 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002252
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002253 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002254
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002255 hwc_layer_1_t* layer = &list->hwLayers[index];
2256 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302257 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002258 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302259 continue;
2260 }
2261 }
2262
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002263 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002264 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002265 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002266 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002267 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002268
Saurabh Shahc62f3982014-03-05 14:28:26 -08002269 Overlay::PipeSpecs pipeSpecs;
2270 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2271 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2272 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2273 (qdutils::MDPVersion::getInstance().is8x26() and
2274 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2275 pipeSpecs.dpy = mDpy;
2276 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002277 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002278
Saurabh Shahc62f3982014-03-05 14:28:26 -08002279 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2280
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002281 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002282 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002283 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002284 }
2285 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002286 return true;
2287}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002288
radhakrishnac9a67412013-09-25 17:40:42 +05302289int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2290 PipeLayerPair& PipeLayerPair) {
2291 MdpYUVPipeInfo& mdp_info =
2292 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2293 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302294 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302295 eDest lDest = mdp_info.lIndex;
2296 eDest rDest = mdp_info.rIndex;
2297
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002298 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302299 lDest, rDest, &PipeLayerPair.rot);
2300}
2301
Saurabh Shah88e4d272013-09-03 13:31:29 -07002302bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002303
Raj Kamal4393eaa2014-06-06 13:45:20 +05302304 if(!isEnabled() or !mModeOn) {
2305 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302306 return true;
2307 }
2308
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002309 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002310 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002311
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002312 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2313 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002314 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002315 if(mCurrentFrame.isFBComposed[i]) continue;
2316
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002317 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002318 private_handle_t *hnd = (private_handle_t *)layer->handle;
2319 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002320 if (!(layer->flags & HWC_COLOR_FILL)) {
2321 ALOGE("%s handle null", __FUNCTION__);
2322 return false;
2323 }
2324 // No PLAY for Color layer
2325 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2326 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002327 }
2328
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002329 int mdpIndex = mCurrentFrame.layerToMDP[i];
2330
Raj Kamal389d6e32014-08-04 14:43:24 +05302331 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302332 {
2333 MdpYUVPipeInfo& pipe_info =
2334 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2335 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2336 ovutils::eDest indexL = pipe_info.lIndex;
2337 ovutils::eDest indexR = pipe_info.rIndex;
2338 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302339 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302340 if(rot) {
2341 rot->queueBuffer(fd, offset);
2342 fd = rot->getDstMemId();
2343 offset = rot->getDstOffset();
2344 }
2345 if(indexL != ovutils::OV_INVALID) {
2346 ovutils::eDest destL = (ovutils::eDest)indexL;
2347 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2348 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2349 if (!ov.queueBuffer(fd, offset, destL)) {
2350 ALOGE("%s: queueBuffer failed for display:%d",
2351 __FUNCTION__, mDpy);
2352 return false;
2353 }
2354 }
2355
2356 if(indexR != ovutils::OV_INVALID) {
2357 ovutils::eDest destR = (ovutils::eDest)indexR;
2358 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2359 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2360 if (!ov.queueBuffer(fd, offset, destR)) {
2361 ALOGE("%s: queueBuffer failed for display:%d",
2362 __FUNCTION__, mDpy);
2363 return false;
2364 }
2365 }
2366 }
2367 else{
2368 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002369 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302370 ovutils::eDest dest = pipe_info.index;
2371 if(dest == ovutils::OV_INVALID) {
2372 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002373 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302374 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002375
radhakrishnac9a67412013-09-25 17:40:42 +05302376 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2377 continue;
2378 }
2379
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002380 int fd = hnd->fd;
2381 uint32_t offset = (uint32_t)hnd->offset;
2382 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2383 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002384 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002385 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002386 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002387 }
2388
radhakrishnac9a67412013-09-25 17:40:42 +05302389 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2390 using pipe: %d", __FUNCTION__, layer,
2391 hnd, dest );
2392
radhakrishnac9a67412013-09-25 17:40:42 +05302393 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2394 if(rot) {
2395 if(!rot->queueBuffer(fd, offset))
2396 return false;
2397 fd = rot->getDstMemId();
2398 offset = rot->getDstOffset();
2399 }
2400
2401 if (!ov.queueBuffer(fd, offset, dest)) {
2402 ALOGE("%s: queueBuffer failed for display:%d ",
2403 __FUNCTION__, mDpy);
2404 return false;
2405 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002406 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002407
2408 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002409 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002410 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002411}
2412
Saurabh Shah88e4d272013-09-03 13:31:29 -07002413//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002414
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002415void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302416 hwc_display_contents_1_t* list){
2417 //if 4kx2k yuv layer is totally present in either in left half
2418 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302419 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302420 if(mCurrentFrame.fbZ >= 0) {
2421 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2422 index++) {
2423 if(!mCurrentFrame.isFBComposed[index]) {
2424 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2425 mdpNextZOrder++;
2426 }
2427 mdpNextZOrder++;
2428 hwc_layer_1_t* layer = &list->hwLayers[index];
2429 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002430 if(isYUVSplitNeeded(hnd) ||
2431 (needs3DComposition(ctx,mDpy) &&
2432 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302433 hwc_rect_t dst = layer->displayFrame;
2434 if((dst.left > lSplit) || (dst.right < lSplit)) {
2435 mCurrentFrame.mdpCount += 1;
2436 }
2437 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2438 mCurrentFrame.fbZ += 1;
2439 mdpNextZOrder++;
2440 }
2441 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002442 }
radhakrishnac9a67412013-09-25 17:40:42 +05302443 }
2444}
2445
Saurabh Shah88e4d272013-09-03 13:31:29 -07002446bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002447 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002448
Saurabh Shahc62f3982014-03-05 14:28:26 -08002449 const int lSplit = getLeftSplit(ctx, mDpy);
2450 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002451 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002452 pipe_info.lIndex = ovutils::OV_INVALID;
2453 pipe_info.rIndex = ovutils::OV_INVALID;
2454
Saurabh Shahc62f3982014-03-05 14:28:26 -08002455 Overlay::PipeSpecs pipeSpecs;
2456 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2457 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2458 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2459 pipeSpecs.dpy = mDpy;
2460 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2461 pipeSpecs.fb = false;
2462
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002463 // Acquire pipe only for the updating half
2464 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2465 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2466
2467 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002468 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002469 if(pipe_info.lIndex == ovutils::OV_INVALID)
2470 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002471 }
2472
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002473 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002474 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2475 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002476 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002477 return false;
2478 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002479
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002480 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002481}
2482
Saurabh Shah88e4d272013-09-03 13:31:29 -07002483bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002484 hwc_display_contents_1_t* list) {
2485 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002486
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002487 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002488
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002489 hwc_layer_1_t* layer = &list->hwLayers[index];
2490 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302491 hwc_rect_t dst = layer->displayFrame;
2492 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302493 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302494 if((dst.left > lSplit)||(dst.right < lSplit)){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002495 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302496 continue;
2497 }
2498 }
2499 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002500 //XXX: Check for forced 2D composition
2501 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2502 if(allocSplitVGPipes(ctx,index))
2503 continue;
2504
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002505 int mdpIndex = mCurrentFrame.layerToMDP[index];
2506 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002507 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002508 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002509 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002510
Saurabh Shahc62f3982014-03-05 14:28:26 -08002511 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2512 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2513 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002514 return false;
2515 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002516 }
2517 return true;
2518}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002519
radhakrishnac9a67412013-09-25 17:40:42 +05302520int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2521 PipeLayerPair& PipeLayerPair) {
2522 const int lSplit = getLeftSplit(ctx, mDpy);
2523 hwc_rect_t dst = layer->displayFrame;
2524 if((dst.left > lSplit)||(dst.right < lSplit)){
2525 MdpYUVPipeInfo& mdp_info =
2526 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2527 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302528 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302529 eDest lDest = mdp_info.lIndex;
2530 eDest rDest = mdp_info.rIndex;
2531
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002532 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302533 lDest, rDest, &PipeLayerPair.rot);
2534 }
2535 else{
2536 return configure(ctx, layer, PipeLayerPair);
2537 }
2538}
2539
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002540/*
2541 * Configures pipe(s) for MDP composition
2542 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002543int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002544 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002545 MdpPipeInfoSplit& mdp_info =
2546 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002547 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302548 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002549 eDest lDest = mdp_info.lIndex;
2550 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002551
2552 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002553 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002554
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002555 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002556 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002557}
2558
Saurabh Shah88e4d272013-09-03 13:31:29 -07002559bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002560
Raj Kamal4393eaa2014-06-06 13:45:20 +05302561 if(!isEnabled() or !mModeOn) {
2562 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302563 return true;
2564 }
2565
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002566 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002567 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002568
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002569 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2570 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002571 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002572 if(mCurrentFrame.isFBComposed[i]) continue;
2573
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002574 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002575 private_handle_t *hnd = (private_handle_t *)layer->handle;
2576 if(!hnd) {
2577 ALOGE("%s handle null", __FUNCTION__);
2578 return false;
2579 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002580
2581 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2582 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002583 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002584
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002585 int mdpIndex = mCurrentFrame.layerToMDP[i];
2586
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002587 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2588 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302589 {
2590 MdpYUVPipeInfo& pipe_info =
2591 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2592 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2593 ovutils::eDest indexL = pipe_info.lIndex;
2594 ovutils::eDest indexR = pipe_info.rIndex;
2595 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302596 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302597 if(rot) {
2598 rot->queueBuffer(fd, offset);
2599 fd = rot->getDstMemId();
2600 offset = rot->getDstOffset();
2601 }
2602 if(indexL != ovutils::OV_INVALID) {
2603 ovutils::eDest destL = (ovutils::eDest)indexL;
2604 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2605 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2606 if (!ov.queueBuffer(fd, offset, destL)) {
2607 ALOGE("%s: queueBuffer failed for display:%d",
2608 __FUNCTION__, mDpy);
2609 return false;
2610 }
2611 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002612
radhakrishnac9a67412013-09-25 17:40:42 +05302613 if(indexR != ovutils::OV_INVALID) {
2614 ovutils::eDest destR = (ovutils::eDest)indexR;
2615 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2616 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2617 if (!ov.queueBuffer(fd, offset, destR)) {
2618 ALOGE("%s: queueBuffer failed for display:%d",
2619 __FUNCTION__, mDpy);
2620 return false;
2621 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002622 }
2623 }
radhakrishnac9a67412013-09-25 17:40:42 +05302624 else{
2625 MdpPipeInfoSplit& pipe_info =
2626 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2627 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002628
radhakrishnac9a67412013-09-25 17:40:42 +05302629 ovutils::eDest indexL = pipe_info.lIndex;
2630 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002631
radhakrishnac9a67412013-09-25 17:40:42 +05302632 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002633 uint32_t offset = (uint32_t)hnd->offset;
2634 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2635 if (!mDpy && (index != -1)) {
2636 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2637 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002638 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002639 }
radhakrishnac9a67412013-09-25 17:40:42 +05302640
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002641 if(ctx->mAD->draw(ctx, fd, offset)) {
2642 fd = ctx->mAD->getDstFd();
2643 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002644 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002645
radhakrishnac9a67412013-09-25 17:40:42 +05302646 if(rot) {
2647 rot->queueBuffer(fd, offset);
2648 fd = rot->getDstMemId();
2649 offset = rot->getDstOffset();
2650 }
2651
2652 //************* play left mixer **********
2653 if(indexL != ovutils::OV_INVALID) {
2654 ovutils::eDest destL = (ovutils::eDest)indexL;
2655 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2656 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2657 if (!ov.queueBuffer(fd, offset, destL)) {
2658 ALOGE("%s: queueBuffer failed for left mixer",
2659 __FUNCTION__);
2660 return false;
2661 }
2662 }
2663
2664 //************* play right mixer **********
2665 if(indexR != ovutils::OV_INVALID) {
2666 ovutils::eDest destR = (ovutils::eDest)indexR;
2667 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2668 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2669 if (!ov.queueBuffer(fd, offset, destR)) {
2670 ALOGE("%s: queueBuffer failed for right mixer",
2671 __FUNCTION__);
2672 return false;
2673 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002674 }
2675 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002676
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002677 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2678 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002679
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002680 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002681}
Saurabh Shahab47c692014-02-12 18:45:57 -08002682
2683//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002684
2685bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2686 hwc_display_contents_1_t* list) {
2687 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2688 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2689
2690 for(int i = numAppLayers - 1; i >= 0; i--) {
2691 if(!isValidRect(visibleRect)) {
2692 mCurrentFrame.drop[i] = true;
2693 mCurrentFrame.dropCount++;
2694 continue;
2695 }
2696
2697 const hwc_layer_1_t* layer = &list->hwLayers[i];
2698 hwc_rect_t dstRect = layer->displayFrame;
2699 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2700
2701 if(!isValidRect(res)) {
2702 mCurrentFrame.drop[i] = true;
2703 mCurrentFrame.dropCount++;
2704 } else {
2705 /* Reset frame ROI when any layer which needs scaling also needs ROI
2706 * cropping */
2707 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2708 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2709 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2710 mCurrentFrame.dropCount = 0;
2711 return false;
2712 }
2713
2714 /* deduct any opaque region from visibleRect */
2715 if (layer->blending == HWC_BLENDING_NONE &&
2716 layer->planeAlpha == 0xFF)
2717 visibleRect = deductRect(visibleRect, res);
2718 }
2719 }
2720 return true;
2721}
2722
2723/*
2724 * HW Limitation: ping pong split can always split the ping pong output
2725 * equally across two DSI's. So the ROI programmed should be of equal width
2726 * for both the halves
2727 */
2728void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2729 hwc_display_contents_1_t* list) {
2730 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2731
2732
2733 if(!canPartialUpdate(ctx, list))
2734 return;
2735
2736 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2737 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2738 (int)ctx->dpyAttr[mDpy].yres};
2739
2740 for(int index = 0; index < numAppLayers; index++ ) {
2741 hwc_layer_1_t* layer = &list->hwLayers[index];
2742
2743 // If we have a RGB layer which needs rotation, no partial update
2744 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2745 return;
2746
2747 if ((mCachedFrame.hnd[index] != layer->handle) ||
2748 isYuvBuffer((private_handle_t *)layer->handle)) {
2749 hwc_rect_t dst = layer->displayFrame;
2750 hwc_rect_t updatingRect = dst;
2751
2752#ifdef QCOM_BSP
2753 if(!needsScaling(layer) && !layer->transform)
2754 {
2755 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2756 int x_off = dst.left - src.left;
2757 int y_off = dst.top - src.top;
2758 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2759 }
2760#endif
2761
2762 roi = getUnion(roi, updatingRect);
2763 }
2764 }
2765
2766 /* No layer is updating. Still SF wants a refresh.*/
2767 if(!isValidRect(roi))
2768 return;
2769
2770 roi = expandROIFromMidPoint(roi, fullFrame);
2771
2772 hwc_rect lFrame = fullFrame;
2773 lFrame.right /= 2;
2774 hwc_rect lRoi = getIntersection(roi, lFrame);
2775
2776 // Align ROI coordinates to panel restrictions
2777 lRoi = getSanitizeROI(lRoi, lFrame);
2778
2779 hwc_rect rFrame = fullFrame;
2780 rFrame.left = lFrame.right;
2781 hwc_rect rRoi = getIntersection(roi, rFrame);
2782
2783 // Align ROI coordinates to panel restrictions
2784 rRoi = getSanitizeROI(rRoi, rFrame);
2785
2786 roi = getUnion(lRoi, rRoi);
2787
2788 ctx->listStats[mDpy].lRoi = roi;
2789 if(!validateAndApplyROI(ctx, list))
2790 resetROI(ctx, mDpy);
2791
2792 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2793 __FUNCTION__,
2794 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2795 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2796 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2797 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2798}
2799
Saurabh Shahab47c692014-02-12 18:45:57 -08002800bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002801 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002802 private_handle_t *hnd = (private_handle_t *)layer->handle;
2803 hwc_rect_t dst = layer->displayFrame;
2804 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2805 pipe_info.lIndex = ovutils::OV_INVALID;
2806 pipe_info.rIndex = ovutils::OV_INVALID;
2807
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002808 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2809 trimAgainstROI(ctx,crop, dst);
2810
Saurabh Shahab47c692014-02-12 18:45:57 -08002811 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2812 //should have a higher priority than the right one. Pipe priorities are
2813 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002814
Saurabh Shahc62f3982014-03-05 14:28:26 -08002815 Overlay::PipeSpecs pipeSpecs;
2816 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2817 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2818 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2819 pipeSpecs.dpy = mDpy;
2820 pipeSpecs.fb = false;
2821
Saurabh Shahab47c692014-02-12 18:45:57 -08002822 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002823 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002824 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002825 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002826 }
2827
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002828 /* Use 2 pipes IF
2829 a) Layer's crop width is > 2048 or
2830 b) Layer's dest width > 2048 or
2831 c) On primary, driver has indicated with caps to split always. This is
2832 based on an empirically derived value of panel height. Applied only
2833 if the layer's width is > mixer's width
2834 */
2835
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302836 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002837 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302838 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002839 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2840 const uint32_t dstWidth = dst.right - dst.left;
2841 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002842 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002843 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002844 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002845 crop.bottom - crop.top;
2846 //Approximation to actual clock, ignoring the common factors in pipe and
2847 //mixer cases like line_time
2848 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2849 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002850
Saurabh Shah05f4e222015-02-05 14:36:22 -08002851 const uint32_t downscale = getRotDownscale(ctx, layer);
2852 if(downscale) {
2853 cropWidth /= downscale;
2854 cropHeight /= downscale;
2855 }
2856
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002857 if(dstWidth > mdpHw.getMaxPipeWidth() or
2858 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002859 (primarySplitAlways and
2860 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002861 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002862 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002863 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002864 }
2865
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002866 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2867 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002868 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002869 }
2870 }
2871
2872 return true;
2873}
2874
Saurabh Shahab47c692014-02-12 18:45:57 -08002875int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2876 PipeLayerPair& PipeLayerPair) {
2877 private_handle_t *hnd = (private_handle_t *)layer->handle;
2878 if(!hnd) {
2879 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2880 return -1;
2881 }
2882 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2883 MdpPipeInfoSplit& mdp_info =
2884 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2885 Rotator **rot = &PipeLayerPair.rot;
2886 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002887 eDest lDest = mdp_info.lIndex;
2888 eDest rDest = mdp_info.rIndex;
2889 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2890 hwc_rect_t dst = layer->displayFrame;
2891 int transform = layer->transform;
2892 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002893 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002894 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002895 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002896 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08002897
2898 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2899 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2900
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002901 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2902 /* MDP driver crops layer coordinates against ROI in Non-Split
2903 * and Split MDP comp. But HWC needs to crop them for source split.
2904 * Reason: 1) Source split is efficient only when the final effective
2905 * load is distributed evenly across mixers.
2906 * 2) We have to know the effective width of the layer that
2907 * the ROI needs to find the no. of pipes the layer needs.
2908 */
2909 trimAgainstROI(ctx, crop, dst);
2910 }
2911
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002912 if(needs3DComposition(ctx, mDpy) &&
2913 get3DFormat(hnd) != HAL_NO_3D){
2914 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
2915 rDest, &PipeLayerPair.rot);
2916 }
2917
Saurabh Shahab47c692014-02-12 18:45:57 -08002918 // Handle R/B swap
2919 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2920 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2921 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2922 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2923 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2924 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002925 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002926 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2927 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002928 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002929 /* Calculate the external display position based on MDP downscale,
2930 ActionSafe, and extorientation features. */
2931 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002932
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002933 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002934 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002935
2936 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2937 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002938 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002939 }
2940
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002941 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002942 (*rot) = ctx->mRotMgr->getNext();
2943 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002944 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002945 //If the video is using a single pipe, enable BWC
2946 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002947 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2948 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002949 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002950 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002951 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002952 ALOGE("%s: configRotator failed!", __FUNCTION__);
2953 return -1;
2954 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002955 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002956 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002957 }
2958
2959 //If 2 pipes being used, divide layer into half, crop and dst
2960 hwc_rect_t cropL = crop;
2961 hwc_rect_t cropR = crop;
2962 hwc_rect_t dstL = dst;
2963 hwc_rect_t dstR = dst;
2964 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2965 cropL.right = (crop.right + crop.left) / 2;
2966 cropR.left = cropL.right;
2967 sanitizeSourceCrop(cropL, cropR, hnd);
2968
Saurabh Shahb729b192014-08-15 18:04:24 -07002969 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002970 //Swap crops on H flip since 2 pipes are being used
2971 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2972 hwc_rect_t tmp = cropL;
2973 cropL = cropR;
2974 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002975 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002976 }
2977
Saurabh Shahb729b192014-08-15 18:04:24 -07002978 //cropSwap trick: If the src and dst widths are both odd, let us say
2979 //2507, then splitting both into half would cause left width to be 1253
2980 //and right 1254. If crop is swapped because of H flip, this will cause
2981 //left crop width to be 1254, whereas left dst width remains 1253, thus
2982 //inducing a scaling that is unaccounted for. To overcome that we add 1
2983 //to the dst width if there is a cropSwap. So if the original width was
2984 //2507, the left dst width will be 1254. Even if the original width was
2985 //even for ex: 2508, the left dst width will still remain 1254.
2986 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002987 dstR.left = dstL.right;
2988 }
2989
2990 //For the mdp, since either we are pre-rotating or MDP does flips
2991 orient = OVERLAY_TRANSFORM_0;
2992 transform = 0;
2993
2994 //configure left pipe
2995 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002996 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002997 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2998 (ovutils::eBlending) getBlending(layer->blending));
2999
3000 if(configMdp(ctx->mOverlay, pargL, orient,
3001 cropL, dstL, metadata, lDest) < 0) {
3002 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
3003 return -1;
3004 }
3005 }
3006
3007 //configure right pipe
3008 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07003009 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08003010 static_cast<eRotFlags>(rotFlags),
3011 layer->planeAlpha,
3012 (ovutils::eBlending) getBlending(layer->blending));
3013 if(configMdp(ctx->mOverlay, pargR, orient,
3014 cropR, dstR, metadata, rDest) < 0) {
3015 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
3016 return -1;
3017 }
3018 }
3019
3020 return 0;
3021}
3022
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003023bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
3024 Locker::Autolock _l(ctx->mDrawLock);
3025 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3026 char path[MAX_SYSFS_FILE_PATH];
3027 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3028 int fd = open(path, O_RDONLY);
3029 if(fd < 0) {
3030 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
3031 return -1;
3032 }
3033 char value[4];
3034 ssize_t size_read = read(fd, value, sizeof(value)-1);
3035 if(size_read <= 0) {
3036 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
3037 close(fd);
3038 return -1;
3039 }
3040 close(fd);
3041 value[size_read] = '\0';
3042 return atoi(value);
3043}
3044
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003045int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3046 Locker::Autolock _l(ctx->mDrawLock);
3047 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3048 char path[MAX_SYSFS_FILE_PATH];
3049 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3050 int fd = open(path, O_WRONLY);
3051 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003052 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003053 return -1;
3054 }
3055 char value[4];
3056 snprintf(value, sizeof(value), "%d", (int)enable);
3057 ssize_t ret = write(fd, value, strlen(value));
3058 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003059 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003060 close(fd);
3061 return -1;
3062 }
3063 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003064 return 0;
3065}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003066
3067bool MDPComp::loadPerfLib() {
3068 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3069 bool success = false;
3070 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3071 ALOGE("vendor library not set in ro.vendor.extension_library");
3072 return false;
3073 }
3074
3075 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3076 if(sLibPerfHint) {
3077 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3078 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3079 if (!sPerfLockAcquire || !sPerfLockRelease) {
3080 ALOGE("Failed to load symbols for perfLock");
3081 dlclose(sLibPerfHint);
3082 sLibPerfHint = NULL;
3083 return false;
3084 }
3085 success = true;
3086 ALOGI("Successfully Loaded perf hint API's");
3087 } else {
3088 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3089 }
3090 return success;
3091}
3092
3093void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3094 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3095 return;
3096 }
3097 static int count = sPerfHintWindow;
3098 static int perflockFlag = 0;
3099
3100 /* Send hint to mpctl when single layer is updated
3101 * for a successful number of windows. Hint release
3102 * happens immediately upon multiple layer update.
3103 */
3104 if (onlyVideosUpdating(ctx, list)) {
3105 if(count) {
3106 count--;
3107 }
3108 } else {
3109 if (perflockFlag) {
3110 perflockFlag = 0;
3111 sPerfLockRelease(sPerfLockHandle);
3112 }
3113 count = sPerfHintWindow;
3114 }
3115 if (count == 0 && !perflockFlag) {
3116 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3117 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3118 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003119 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003120 perflockFlag = 1;
3121 }
3122 }
3123}
3124
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003125}; //namespace
3126