blob: ba7793e67c5ee74724741ded3a9b5ca85e8a07b9 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, 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>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070022#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070029#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Saurabh Shah59562ff2014-09-30 16:13:12 -070040IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070041bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool 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;
Saurabh Shah88e4d272013-09-03 13:31:29 -070053MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070054 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
55 sSrcSplitEnabled = true;
56 return new MDPCompSrcSplit(dpy);
57 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070058 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080059 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070060 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080061}
62
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080063MDPComp::MDPComp(int dpy):mDpy(dpy){};
64
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070065void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080066{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070067 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
68 return;
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070071 (mDpy == 0) ? "\"PRIMARY\"" :
72 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070073 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
74 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080075 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
76 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
77 (mCurrentFrame.needsRedraw? "YES" : "NO"),
78 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070079 if(isDisplaySplit(ctx, mDpy)) {
80 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
81 "Right: [%d, %d, %d, %d] \n",
82 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
83 ctx->listStats[mDpy].lRoi.right,
84 ctx->listStats[mDpy].lRoi.bottom,
85 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
86 ctx->listStats[mDpy].rRoi.right,
87 ctx->listStats[mDpy].rRoi.bottom);
88 } else {
89 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
90 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
91 ctx->listStats[mDpy].lRoi.right,
92 ctx->listStats[mDpy].lRoi.bottom);
93 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080094 dumpsys_log(buf," --------------------------------------------- \n");
95 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
96 dumpsys_log(buf," --------------------------------------------- \n");
97 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
98 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
99 index,
100 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700101 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700103 (mCurrentFrame.drop[index] ? "DROP" :
104 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800105 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
106 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
107 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800108}
109
110bool MDPComp::init(hwc_context_t *ctx) {
111
112 if(!ctx) {
113 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
114 return false;
115 }
116
Saurabh Shah59562ff2014-09-30 16:13:12 -0700117 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800118
119 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530120 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
121 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800122 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
123 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800124 sEnabled = true;
125 }
126
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700127 sEnableMixedMode = true;
128 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
131 sEnableMixedMode = false;
132 }
133
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700134 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
135
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800136 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700137 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700138 int val = atoi(property);
139 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700140 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800141 }
142
Saurabh Shahacec8e42014-11-25 11:07:04 -0800143 /* Maximum layers allowed to use MDP on secondary panels. If property
144 * doesn't exist, default to 1. Using the property it can be set to 0 or
145 * more.
146 */
147 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
148 int val = atoi(property);
149 sMaxSecLayers = (val >= 0) ? val : 1;
150 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
151 }
152
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400153 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700154 sIdleInvalidator = IdleInvalidator::getInstance();
155 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
156 delete sIdleInvalidator;
157 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400158 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800159 }
radhakrishnac9a67412013-09-25 17:40:42 +0530160
Saurabh Shah7c727642014-06-02 15:47:14 -0700161 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700162 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700163 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
164 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
165 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530166 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530167 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700168
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530169 bool defaultPTOR = false;
170 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
171 //8x16 and 8x39 targets by default
172 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
173 (qdutils::MDPVersion::getInstance().is8x16() ||
174 qdutils::MDPVersion::getInstance().is8x39())) {
175 defaultPTOR = true;
176 }
177
178 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
179 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700180 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
181 HWC_DISPLAY_PRIMARY);
182 }
183
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530184 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
185 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
186 enablePartialUpdateForMDP3 = true;
187 }
188
189 if(!enablePartialUpdateForMDP3 &&
190 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
191 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
192 enablePartialUpdateForMDP3 = true;
193 }
194
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700195 return true;
196}
197
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800198void MDPComp::reset(hwc_context_t *ctx) {
199 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700200 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800201 ctx->mOverlay->clear(mDpy);
202 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700203}
204
Raj Kamal4393eaa2014-06-06 13:45:20 +0530205void MDPComp::reset() {
206 sHandleTimeout = false;
207 mModeOn = false;
208}
209
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700210void MDPComp::timeout_handler(void *udata) {
211 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
212
213 if(!ctx) {
214 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
215 return;
216 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800217 Locker::Autolock _l(ctx->mDrawLock);
218 // Handle timeout event only if the previous composition is MDP or MIXED.
219 if(!sHandleTimeout) {
220 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
221 return;
222 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700223 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700224 ALOGE("%s: HWC proc not registered", __FUNCTION__);
225 return;
226 }
227 sIdleFallBack = true;
228 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700229 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700230}
231
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700232void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
233 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800234 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700235 if(value > maxSupported) {
236 ALOGW("%s: Input exceeds max value supported. Setting to"
237 "max value: %d", __FUNCTION__, maxSupported);
238 }
239 sMaxPipesPerMixer = min(value, maxSupported);
240}
241
Saurabh Shah59562ff2014-09-30 16:13:12 -0700242void MDPComp::setIdleTimeout(const uint32_t& timeout) {
243 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
244
245 if(sIdleInvalidator) {
246 if(timeout <= ONE_REFRESH_PERIOD_MS) {
247 //If the specified timeout is < 1 draw cycle worth, "virtually"
248 //disable idle timeout. The ideal way for clients to disable
249 //timeout is to set it to 0
250 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
251 ALOGI("Disabled idle timeout");
252 return;
253 }
254 sIdleInvalidator->setIdleTimeout(timeout);
255 ALOGI("Idle timeout set to %u", timeout);
256 } else {
257 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
258 }
259}
260
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800261void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800262 hwc_display_contents_1_t* list) {
263 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800264
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800265 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800266 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800267 if(!mCurrentFrame.isFBComposed[index]) {
268 layerProp[index].mFlags |= HWC_MDPCOMP;
269 layer->compositionType = HWC_OVERLAY;
270 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800271 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700272 /* Drop the layer when its already present in FB OR when it lies
273 * outside frame's ROI */
274 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800275 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700276 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800277 }
278 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700279}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500280
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800281void MDPComp::setRedraw(hwc_context_t *ctx,
282 hwc_display_contents_1_t* list) {
283 mCurrentFrame.needsRedraw = false;
284 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
285 (list->flags & HWC_GEOMETRY_CHANGED) ||
286 isSkipPresent(ctx, mDpy)) {
287 mCurrentFrame.needsRedraw = true;
288 }
289}
290
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800291MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700292 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700293 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800294}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800295
Saurabh Shahaa236822013-04-24 18:07:26 -0700296void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700297 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800298 if(mdpToLayer[i].pipeInfo) {
299 delete mdpToLayer[i].pipeInfo;
300 mdpToLayer[i].pipeInfo = NULL;
301 //We dont own the rotator
302 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800303 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800304 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800305
306 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
307 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700308 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800309
Saurabh Shahaa236822013-04-24 18:07:26 -0700310 layerCount = numLayers;
311 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800312 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700313 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800314 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315}
316
Saurabh Shahaa236822013-04-24 18:07:26 -0700317void MDPComp::FrameInfo::map() {
318 // populate layer and MDP maps
319 int mdpIdx = 0;
320 for(int idx = 0; idx < layerCount; idx++) {
321 if(!isFBComposed[idx]) {
322 mdpToLayer[mdpIdx].listIndex = idx;
323 layerToMDP[idx] = mdpIdx++;
324 }
325 }
326}
327
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800328MDPComp::LayerCache::LayerCache() {
329 reset();
330}
331
332void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700333 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530334 memset(&isFBComposed, true, sizeof(isFBComposed));
335 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700337}
338
339void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530340 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700341 for(int i = 0; i < numAppLayers; i++) {
342 hnd[i] = list->hwLayers[i].handle;
343 }
344}
345
346void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700347 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530348 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
349 memcpy(&drop, &curFrame.drop, sizeof(drop));
350}
351
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800352bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
353 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530354 if(layerCount != curFrame.layerCount)
355 return false;
356 for(int i = 0; i < curFrame.layerCount; i++) {
357 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
358 (curFrame.drop[i] != drop[i])) {
359 return false;
360 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800361 if(curFrame.isFBComposed[i] &&
362 (hnd[i] != list->hwLayers[i].handle)){
363 return false;
364 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530365 }
366 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800367}
368
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700369bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
370 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800371 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700372 (not isValidDimension(ctx,layer))
373 //More conditions here, SKIP, sRGB+Blend etc
374 ) {
375 return false;
376 }
377 return true;
378}
379
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530380bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800381 private_handle_t *hnd = (private_handle_t *)layer->handle;
382
383 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700384 if (layer->flags & HWC_COLOR_FILL) {
385 // Color layer
386 return true;
387 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700388 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800389 return false;
390 }
391
Naseer Ahmede850a802013-09-06 13:12:52 -0400392 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400393 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400394 return false;
395
Saurabh Shah62e1d732013-09-17 10:44:05 -0700396 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700398 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700399 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
400 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700401 int dst_w = dst.right - dst.left;
402 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 float w_scale = ((float)crop_w / (float)dst_w);
404 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530405 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700406
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800407 /* Workaround for MDP HW limitation in DSI command mode panels where
408 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
409 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530410 * There also is a HW limilation in MDP, minimum block size is 2x2
411 * Fallback to GPU if height is less than 2.
412 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700413 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800414 return false;
415
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800416 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530417 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800418 const float w_dscale = w_scale;
419 const float h_dscale = h_scale;
420
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800421 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700422
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530423 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700424 /* On targets that doesnt support Decimation (eg.,8x26)
425 * maximum downscale support is overlay pipe downscale.
426 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400427 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530428 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700429 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800430 return false;
431 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700432 // Decimation on macrotile format layers is not supported.
433 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530434 /* Bail out if
435 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700436 * 2. exceeds maximum downscale limit
437 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400438 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530439 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700440 w_dscale > maxMDPDownscale ||
441 h_dscale > maxMDPDownscale) {
442 return false;
443 }
444 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800445 return false;
446 }
447 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700448 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700449 return false;
450 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700451 }
452
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800453 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530454 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800455 const float w_uscale = 1.0f / w_scale;
456 const float h_uscale = 1.0f / h_scale;
457
458 if(w_uscale > upscale || h_uscale > upscale)
459 return false;
460 }
461
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800462 return true;
463}
464
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800465bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700466 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800467
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800468 if(!isEnabled()) {
469 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700470 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530471 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530472 qdutils::MDPVersion::getInstance().is8x16() ||
473 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800474 ctx->mVideoTransFlag &&
475 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700476 //1 Padding round to shift pipes across mixers
477 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
478 __FUNCTION__);
479 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700480 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
481 /* TODO: freeing up all the resources only for the targets having total
482 number of pipes < 8. Need to analyze number of VIG pipes used
483 for primary in previous draw cycle and accordingly decide
484 whether to fall back to full GPU comp or video only comp
485 */
486 if(isSecondaryConfiguring(ctx)) {
487 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
488 __FUNCTION__);
489 ret = false;
490 } else if(ctx->isPaddingRound) {
491 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
492 __FUNCTION__,mDpy);
493 ret = false;
494 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800495 } else if (ctx->isDMAStateChanging) {
496 // Bail out if a padding round has been invoked in order to switch DMA
497 // state to block mode. We need this to cater for the case when a layer
498 // requires rotation in the current frame.
499 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
500 __FUNCTION__);
501 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700502 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800503
Saurabh Shahaa236822013-04-24 18:07:26 -0700504 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800505}
506
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800507void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
508 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
509 fbRect = getIntersection(fbRect, roi);
510}
511
512/* 1) Identify layers that are not visible or lying outside the updating ROI and
513 * drop them from composition.
514 * 2) If we have a scaling layer which needs cropping against generated
515 * ROI, reset ROI to full resolution. */
516bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
517 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700518 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800520
521 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800522 if(!isValidRect(visibleRect)) {
523 mCurrentFrame.drop[i] = true;
524 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800525 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800526 }
527
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700528 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800530 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700531
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700532 if(!isValidRect(res)) {
533 mCurrentFrame.drop[i] = true;
534 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700536 /* Reset frame ROI when any layer which needs scaling also needs ROI
537 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800538 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800539 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700540 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
541 mCurrentFrame.dropCount = 0;
542 return false;
543 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800544
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800545 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530546 if (layer->blending == HWC_BLENDING_NONE &&
547 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800548 visibleRect = deductRect(visibleRect, res);
549 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550 }
551 return true;
552}
553
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800554/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
555 * are updating. If DirtyRegion is applicable, calculate it by accounting all
556 * the changing layer's dirtyRegion. */
557void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
558 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700559 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800560 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700561 return;
562
563 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800564 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
565 (int)ctx->dpyAttr[mDpy].yres};
566
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700567 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800568 hwc_layer_1_t* layer = &list->hwLayers[index];
569 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800570 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700571 hwc_rect_t dst = layer->displayFrame;
572 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800573
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800574#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700576 {
577 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
578 int x_off = dst.left - src.left;
579 int y_off = dst.top - src.top;
580 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
581 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800582#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800583
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800584 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700585 }
586 }
587
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800588 /* No layer is updating. Still SF wants a refresh.*/
589 if(!isValidRect(roi))
590 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800591
592 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800593 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800594
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800595 ctx->listStats[mDpy].lRoi = roi;
596 if(!validateAndApplyROI(ctx, list))
597 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700598
599 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800600 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
601 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
602}
603
604void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
605 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
606 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
607
608 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
609 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
610 fbRect = getUnion(l_fbRect, r_fbRect);
611}
612/* 1) Identify layers that are not visible or lying outside BOTH the updating
613 * ROI's and drop them from composition. If a layer is spanning across both
614 * the halves of the screen but needed by only ROI, the non-contributing
615 * half will not be programmed for MDP.
616 * 2) If we have a scaling layer which needs cropping against generated
617 * ROI, reset ROI to full resolution. */
618bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
619 hwc_display_contents_1_t* list) {
620
621 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
622
623 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
624 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
625
626 for(int i = numAppLayers - 1; i >= 0; i--){
627 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
628 {
629 mCurrentFrame.drop[i] = true;
630 mCurrentFrame.dropCount++;
631 continue;
632 }
633
634 const hwc_layer_1_t* layer = &list->hwLayers[i];
635 hwc_rect_t dstRect = layer->displayFrame;
636
637 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
638 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
639 hwc_rect_t res = getUnion(l_res, r_res);
640
641 if(!isValidRect(l_res) && !isValidRect(r_res)) {
642 mCurrentFrame.drop[i] = true;
643 mCurrentFrame.dropCount++;
644 } else {
645 /* Reset frame ROI when any layer which needs scaling also needs ROI
646 * cropping */
647 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
648 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
649 mCurrentFrame.dropCount = 0;
650 return false;
651 }
652
radhakrishna4efbdd62014-11-03 13:19:27 +0530653 if (layer->blending == HWC_BLENDING_NONE &&
654 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800655 visibleRectL = deductRect(visibleRectL, l_res);
656 visibleRectR = deductRect(visibleRectR, r_res);
657 }
658 }
659 }
660 return true;
661}
662/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
663 * are updating. If DirtyRegion is applicable, calculate it by accounting all
664 * the changing layer's dirtyRegion. */
665void MDPCompSplit::generateROI(hwc_context_t *ctx,
666 hwc_display_contents_1_t* list) {
667 if(!canPartialUpdate(ctx, list))
668 return;
669
670 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
671 int lSplit = getLeftSplit(ctx, mDpy);
672
673 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
674 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
675
676 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
677 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
678
679 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
680 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
681
682 for(int index = 0; index < numAppLayers; index++ ) {
683 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800684 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800685 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800686 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700687 hwc_rect_t dst = layer->displayFrame;
688 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800689
690#ifdef QCOM_BSP
691 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700692 {
693 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
694 int x_off = dst.left - src.left;
695 int y_off = dst.top - src.top;
696 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
697 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800698#endif
699
700 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
701 if(isValidRect(l_dst))
702 l_roi = getUnion(l_roi, l_dst);
703
704 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
705 if(isValidRect(r_dst))
706 r_roi = getUnion(r_roi, r_dst);
707 }
708 }
709
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700710 /* For panels that cannot accept commands in both the interfaces, we cannot
711 * send two ROI's (for each half). We merge them into single ROI and split
712 * them across lSplit for MDP mixer use. The ROI's will be merged again
713 * finally before udpating the panel in the driver. */
714 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
715 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
716 l_roi = getIntersection(temp_roi, l_frame);
717 r_roi = getIntersection(temp_roi, r_frame);
718 }
719
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800720 /* No layer is updating. Still SF wants a refresh. */
721 if(!isValidRect(l_roi) && !isValidRect(r_roi))
722 return;
723
724 l_roi = getSanitizeROI(l_roi, l_frame);
725 r_roi = getSanitizeROI(r_roi, r_frame);
726
727 ctx->listStats[mDpy].lRoi = l_roi;
728 ctx->listStats[mDpy].rRoi = r_roi;
729
730 if(!validateAndApplyROI(ctx, list))
731 resetROI(ctx, mDpy);
732
733 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
734 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
735 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
736 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
737 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
738 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700739}
740
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800741/* Checks for conditions where all the layers marked for MDP comp cannot be
742 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800743bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800744 hwc_display_contents_1_t* list){
745
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800747
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700748 // Fall back to video only composition, if AIV video mode is enabled
749 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700750 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
751 __FUNCTION__, mDpy);
752 return false;
753 }
754
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400755 // No Idle fall back, if secure display or secure RGB layers are present or
756 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700757 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400758 !ctx->listStats[mDpy].secureRGBCount) &&
759 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700760 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
761 return false;
762 }
763
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800764 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700765 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
766 __FUNCTION__,
767 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800768 return false;
769 }
770
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700771 // if secondary is configuring or Padding round, fall back to video only
772 // composition and release all assigned non VIG pipes from primary.
773 if(isSecondaryConfiguring(ctx)) {
774 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
775 __FUNCTION__);
776 return false;
777 } else if(ctx->isPaddingRound) {
778 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
779 __FUNCTION__,mDpy);
780 return false;
781 }
782
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700783 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800784 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700785 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800786 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
787 return false;
788 }
789
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800790 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800791 hwc_layer_1_t* layer = &list->hwLayers[i];
792 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800793
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800794 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700795 if(!canUseRotator(ctx, mDpy)) {
796 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
797 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700798 return false;
799 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800800 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530801
802 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
803 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800804 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700805 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530806 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
807 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
808 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800809 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700810
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700811 if(ctx->mAD->isDoable()) {
812 return false;
813 }
814
Saurabh Shahaa236822013-04-24 18:07:26 -0700815 //If all above hard conditions are met we can do full or partial MDP comp.
816 bool ret = false;
817 if(fullMDPComp(ctx, list)) {
818 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700819 } else if(fullMDPCompWithPTOR(ctx, list)) {
820 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700821 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700822 ret = true;
823 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530824
Saurabh Shahaa236822013-04-24 18:07:26 -0700825 return ret;
826}
827
828bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700829
830 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
831 return false;
832
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700833 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
834 for(int i = 0; i < numAppLayers; i++) {
835 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700836 if(not mCurrentFrame.drop[i] and
837 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700838 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
839 return false;
840 }
841 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800842
Saurabh Shahaa236822013-04-24 18:07:26 -0700843 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700844 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
845 sizeof(mCurrentFrame.isFBComposed));
846 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
847 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700848
Raj Kamal389d6e32014-08-04 14:43:24 +0530849 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800850 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530851 }
852
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800853 if(!postHeuristicsHandling(ctx, list)) {
854 ALOGD_IF(isDebug(), "post heuristic handling failed");
855 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700856 return false;
857 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700858 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
859 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700860 return true;
861}
862
Sushil Chauhandefd3522014-05-13 18:17:12 -0700863/* Full MDP Composition with Peripheral Tiny Overlap Removal.
864 * MDP bandwidth limitations can be avoided, if the overlap region
865 * covered by the smallest layer at a higher z-order, gets composed
866 * by Copybit on a render buffer, which can be queued to MDP.
867 */
868bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
869 hwc_display_contents_1_t* list) {
870
871 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
872 const int stagesForMDP = min(sMaxPipesPerMixer,
873 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
874
875 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700876 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700877 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
878 return false;
879 }
880
881 // Frame level checks
882 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
883 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
884 isSecurePresent(ctx, mDpy)) {
885 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
886 return false;
887 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 // MDP comp checks
889 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700890 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700891 if(not isSupportedForMDPComp(ctx, layer)) {
892 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
893 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700894 }
895 }
896
Sushil Chauhandefd3522014-05-13 18:17:12 -0700897 /* We cannot use this composition mode, if:
898 1. A below layer needs scaling.
899 2. Overlap is not peripheral to display.
900 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700901 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700902 */
903
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700904 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
905 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
906 memset(overlapRect, 0, sizeof(overlapRect));
907 int layerPixelCount, minPixelCount = 0;
908 int numPTORLayersFound = 0;
909 for (int i = numAppLayers-1; (i >= 0 &&
910 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700912 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700913 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700914 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
915 // PTOR layer should be peripheral and cannot have transform
916 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
917 has90Transform(layer)) {
918 continue;
919 }
920 if((3 * (layerPixelCount + minPixelCount)) >
921 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
922 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
923 continue;
924 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700925 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700926 for (int j = i-1; j >= 0; j--) {
927 // Check if the layers below this layer qualifies for PTOR comp
928 hwc_layer_1_t* layer = &list->hwLayers[j];
929 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700930 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700931 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700932 if (isValidRect(getIntersection(dispFrame, disFrame))) {
933 if (has90Transform(layer) || needsScaling(layer)) {
934 found = false;
935 break;
936 }
937 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 }
939 }
940 // Store the minLayer Index
941 if(found) {
942 minLayerIndex[numPTORLayersFound] = i;
943 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
944 minPixelCount += layerPixelCount;
945 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700946 }
947 }
948
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700949 // No overlap layers
950 if (!numPTORLayersFound)
951 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700952
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700953 // Store the displayFrame and the sourceCrops of the layers
954 hwc_rect_t displayFrame[numAppLayers];
955 hwc_rect_t sourceCrop[numAppLayers];
956 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700957 hwc_layer_1_t* layer = &list->hwLayers[i];
958 displayFrame[i] = layer->displayFrame;
959 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700960 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700961
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530962 /**
963 * It's possible that 2 PTOR layers might have overlapping.
964 * In such case, remove the intersection(again if peripheral)
965 * from the lower PTOR layer to avoid overlapping.
966 * If intersection is not on peripheral then compromise
967 * by reducing number of PTOR layers.
968 **/
969 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
970 if(isValidRect(commonRect)) {
971 overlapRect[1] = deductRect(overlapRect[1], commonRect);
972 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
973 }
974
975 ctx->mPtorInfo.count = numPTORLayersFound;
976 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
977 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
978 }
979
980 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
981 // reset PTOR
982 ctx->mPtorInfo.count = 0;
983 if(isValidRect(commonRect)) {
984 // If PTORs are intersecting restore displayframe of PTOR[1]
985 // before returning, as we have modified it above.
986 list->hwLayers[minLayerIndex[1]].displayFrame =
987 displayFrame[minLayerIndex[1]];
988 }
989 return false;
990 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700991 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
992 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
993
Xu Yangcda012c2014-07-30 21:57:21 +0800994 // Store the blending mode, planeAlpha, and transform of PTOR layers
995 int32_t blending[numPTORLayersFound];
996 uint8_t planeAlpha[numPTORLayersFound];
997 uint32_t transform[numPTORLayersFound];
998
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700999 for(int j = 0; j < numPTORLayersFound; j++) {
1000 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001001
1002 // Update src crop of PTOR layer
1003 hwc_layer_1_t* layer = &list->hwLayers[index];
1004 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1005 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1006 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1007 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1008
1009 // Store & update w, h, format of PTOR layer
1010 private_handle_t *hnd = (private_handle_t *)layer->handle;
1011 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1012 layerWhf[j] = whf;
1013 hnd->width = renderBuf->width;
1014 hnd->height = renderBuf->height;
1015 hnd->format = renderBuf->format;
1016
Xu Yangcda012c2014-07-30 21:57:21 +08001017 // Store & update blending mode, planeAlpha and transform of PTOR layer
1018 blending[j] = layer->blending;
1019 planeAlpha[j] = layer->planeAlpha;
1020 transform[j] = layer->transform;
1021 layer->blending = HWC_BLENDING_NONE;
1022 layer->planeAlpha = 0xFF;
1023 layer->transform = 0;
1024
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001025 // Remove overlap from crop & displayFrame of below layers
1026 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001027 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001028 if(!isValidRect(getIntersection(layer->displayFrame,
1029 overlapRect[j]))) {
1030 continue;
1031 }
1032 // Update layer attributes
1033 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1034 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301035 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001036 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1037 layer->transform);
1038 layer->sourceCropf.left = (float)srcCrop.left;
1039 layer->sourceCropf.top = (float)srcCrop.top;
1040 layer->sourceCropf.right = (float)srcCrop.right;
1041 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1042 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001043 }
1044
1045 mCurrentFrame.mdpCount = numAppLayers;
1046 mCurrentFrame.fbCount = 0;
1047 mCurrentFrame.fbZ = -1;
1048
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301049 for (int j = 0; j < numAppLayers; j++) {
1050 if(isValidRect(list->hwLayers[j].displayFrame)) {
1051 mCurrentFrame.isFBComposed[j] = false;
1052 } else {
1053 mCurrentFrame.mdpCount--;
1054 mCurrentFrame.drop[j] = true;
1055 }
1056 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001057
1058 bool result = postHeuristicsHandling(ctx, list);
1059
1060 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001061 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001062 hwc_layer_1_t* layer = &list->hwLayers[i];
1063 layer->displayFrame = displayFrame[i];
1064 layer->sourceCropf.left = (float)sourceCrop[i].left;
1065 layer->sourceCropf.top = (float)sourceCrop[i].top;
1066 layer->sourceCropf.right = (float)sourceCrop[i].right;
1067 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1068 }
1069
Xu Yangcda012c2014-07-30 21:57:21 +08001070 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001071 for (int i = 0; i < numPTORLayersFound; i++) {
1072 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001073 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001074 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1075 hnd->width = layerWhf[i].w;
1076 hnd->height = layerWhf[i].h;
1077 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001078 layer->blending = blending[i];
1079 layer->planeAlpha = planeAlpha[i];
1080 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001081 }
1082
Sushil Chauhandefd3522014-05-13 18:17:12 -07001083 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001084 // reset PTOR
1085 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001086 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001087 } else {
1088 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1089 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001090 }
1091
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001092 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1093 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001094 return result;
1095}
1096
Saurabh Shahaa236822013-04-24 18:07:26 -07001097bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1098{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001099 if(!sEnableMixedMode) {
1100 //Mixed mode is disabled. No need to even try caching.
1101 return false;
1102 }
1103
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001104 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001105 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001106 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001107 cacheBasedComp(ctx, list);
1108 } else {
1109 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001110 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001111 }
1112
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001113 return ret;
1114}
1115
1116bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1117 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001118 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1119 return false;
1120
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001121 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001122 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001123 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001124
1125 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1126 for(int i = 0; i < numAppLayers; i++) {
1127 if(!mCurrentFrame.isFBComposed[i]) {
1128 hwc_layer_1_t* layer = &list->hwLayers[i];
1129 if(not isSupportedForMDPComp(ctx, layer)) {
1130 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1131 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001132 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001133 return false;
1134 }
1135 }
1136 }
1137
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001138 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001139 /* mark secure RGB layers for MDP comp */
1140 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301141 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001142 if(!ret) {
1143 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001144 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001145 return false;
1146 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001147
1148 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001149
Raj Kamal389d6e32014-08-04 14:43:24 +05301150 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001151 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301152 }
1153
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001154 if(!postHeuristicsHandling(ctx, list)) {
1155 ALOGD_IF(isDebug(), "post heuristic handling failed");
1156 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001157 return false;
1158 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001159 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1160 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001161
Saurabh Shahaa236822013-04-24 18:07:26 -07001162 return true;
1163}
1164
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001165bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001166 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001167 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1168 return false;
1169
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001170 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001171 return false;
1172 }
1173
Saurabh Shahb772ae32013-11-18 15:40:02 -08001174 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001175 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1176 const int stagesForMDP = min(sMaxPipesPerMixer,
1177 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001178
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001179 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1180 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1181 int lastMDPSupportedIndex = numAppLayers;
1182 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001183
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001184 //Find the minimum MDP batch size
1185 for(int i = 0; i < numAppLayers;i++) {
1186 if(mCurrentFrame.drop[i]) {
1187 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001188 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001189 }
1190 hwc_layer_1_t* layer = &list->hwLayers[i];
1191 if(not isSupportedForMDPComp(ctx, layer)) {
1192 lastMDPSupportedIndex = i;
1193 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1194 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001195 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001196 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001197 }
1198
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001199 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1200 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1201 mCurrentFrame.dropCount);
1202
1203 //Start at a point where the fb batch should at least have 2 layers, for
1204 //this mode to be justified.
1205 while(fbBatchSize < 2) {
1206 ++fbBatchSize;
1207 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001208 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001209
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001210 //If there are no layers for MDP, this mode doesnt make sense.
1211 if(mdpBatchSize < 1) {
1212 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1213 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001214 return false;
1215 }
1216
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001217 mCurrentFrame.reset(numAppLayers);
1218
1219 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1220 while(mdpBatchSize > 0) {
1221 //Mark layers for MDP comp
1222 int mdpBatchLeft = mdpBatchSize;
1223 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1224 if(mCurrentFrame.drop[i]) {
1225 continue;
1226 }
1227 mCurrentFrame.isFBComposed[i] = false;
1228 --mdpBatchLeft;
1229 }
1230
1231 mCurrentFrame.fbZ = mdpBatchSize;
1232 mCurrentFrame.fbCount = fbBatchSize;
1233 mCurrentFrame.mdpCount = mdpBatchSize;
1234
1235 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1236 __FUNCTION__, mdpBatchSize, fbBatchSize,
1237 mCurrentFrame.dropCount);
1238
1239 if(postHeuristicsHandling(ctx, list)) {
1240 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001241 __FUNCTION__);
1242 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1243 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001244 return true;
1245 }
1246
1247 reset(ctx);
1248 --mdpBatchSize;
1249 ++fbBatchSize;
1250 }
1251
1252 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001253}
1254
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001255bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301256 if(mDpy or isSecurePresent(ctx, mDpy) or
1257 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001258 return false;
1259 }
1260 return true;
1261}
1262
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001263bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1264 hwc_display_contents_1_t* list){
1265 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1266 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001267 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001268 return false;
1269 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001270 if(ctx->listStats[mDpy].secureUI)
1271 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001272 return true;
1273}
1274
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001275bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1276 hwc_display_contents_1_t* list) {
1277 const bool secureOnly = true;
1278 return videoOnlyComp(ctx, list, not secureOnly) or
1279 videoOnlyComp(ctx, list, secureOnly);
1280}
1281
1282bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001283 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001284 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1285 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001286 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001287
Saurabh Shahaa236822013-04-24 18:07:26 -07001288 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001289 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001290 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001291 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001292
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001293 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1294 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001295 return false;
1296 }
1297
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001298 /* Bail out if we are processing only secured video layers
1299 * and we dont have any */
1300 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001301 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001302 return false;
1303 }
1304
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001305 if(mCurrentFrame.fbCount)
1306 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001307
Raj Kamal389d6e32014-08-04 14:43:24 +05301308 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001309 adjustForSourceSplit(ctx, list);
1310 }
1311
1312 if(!postHeuristicsHandling(ctx, list)) {
1313 ALOGD_IF(isDebug(), "post heuristic handling failed");
1314 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001315 return false;
1316 }
1317
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001318 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1319 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001320 return true;
1321}
1322
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001323/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1324bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1325 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001326 // Fall back to video only composition, if AIV video mode is enabled
1327 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001328 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1329 __FUNCTION__, mDpy);
1330 return false;
1331 }
1332
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001333 const bool secureOnly = true;
1334 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1335 mdpOnlyLayersComp(ctx, list, secureOnly);
1336
1337}
1338
1339bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1340 hwc_display_contents_1_t* list, bool secureOnly) {
1341
1342 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1343 return false;
1344
1345 /* Bail out if we are processing only secured video layers
1346 * and we dont have any */
1347 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1348 reset(ctx);
1349 return false;
1350 }
1351
1352 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1353 mCurrentFrame.reset(numAppLayers);
1354 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1355
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001356 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001357 /* mark secure RGB layers for MDP comp */
1358 updateSecureRGB(ctx, list);
1359
1360 if(mCurrentFrame.mdpCount == 0) {
1361 reset(ctx);
1362 return false;
1363 }
1364
1365 /* find the maximum batch of layers to be marked for framebuffer */
1366 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1367 if(!ret) {
1368 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1369 reset(ctx);
1370 return false;
1371 }
1372
1373 if(sEnableYUVsplit){
1374 adjustForSourceSplit(ctx, list);
1375 }
1376
1377 if(!postHeuristicsHandling(ctx, list)) {
1378 ALOGD_IF(isDebug(), "post heuristic handling failed");
1379 reset(ctx);
1380 return false;
1381 }
1382
1383 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1384 __FUNCTION__);
1385 return true;
1386}
1387
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001388/* Checks for conditions where YUV layers cannot be bypassed */
1389bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001390 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001391 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001392 return false;
1393 }
1394
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001395 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001396 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1397 return false;
1398 }
1399
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001400 if(isSecuring(ctx, layer)) {
1401 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1402 return false;
1403 }
1404
Saurabh Shah4fdde762013-04-30 18:47:33 -07001405 if(!isValidDimension(ctx, layer)) {
1406 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1407 __FUNCTION__);
1408 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001409 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001410
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001411 if(layer->planeAlpha < 0xFF) {
1412 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1413 in video only mode",
1414 __FUNCTION__);
1415 return false;
1416 }
1417
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001418 return true;
1419}
1420
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001421/* Checks for conditions where Secure RGB layers cannot be bypassed */
1422bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1423 if(isSkipLayer(layer)) {
1424 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1425 __FUNCTION__, mDpy);
1426 return false;
1427 }
1428
1429 if(isSecuring(ctx, layer)) {
1430 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1431 return false;
1432 }
1433
1434 if(not isSupportedForMDPComp(ctx, layer)) {
1435 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1436 __FUNCTION__);
1437 return false;
1438 }
1439 return true;
1440}
1441
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301442/* starts at fromIndex and check for each layer to find
1443 * if it it has overlapping with any Updating layer above it in zorder
1444 * till the end of the batch. returns true if it finds any intersection */
1445bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1446 int fromIndex, int toIndex) {
1447 for(int i = fromIndex; i < toIndex; i++) {
1448 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1449 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1450 return false;
1451 }
1452 }
1453 }
1454 return true;
1455}
1456
1457/* Checks if given layer at targetLayerIndex has any
1458 * intersection with all the updating layers in beween
1459 * fromIndex and toIndex. Returns true if it finds intersectiion */
1460bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1461 int fromIndex, int toIndex, int targetLayerIndex) {
1462 for(int i = fromIndex; i <= toIndex; i++) {
1463 if(!mCurrentFrame.isFBComposed[i]) {
1464 if(areLayersIntersecting(&list->hwLayers[i],
1465 &list->hwLayers[targetLayerIndex])) {
1466 return true;
1467 }
1468 }
1469 }
1470 return false;
1471}
1472
1473int MDPComp::getBatch(hwc_display_contents_1_t* list,
1474 int& maxBatchStart, int& maxBatchEnd,
1475 int& maxBatchCount) {
1476 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301477 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001478 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301479 while (i < mCurrentFrame.layerCount) {
1480 int batchCount = 0;
1481 int batchStart = i;
1482 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001483 /* Adjust batch Z order with the dropped layers so far */
1484 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301485 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301486 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301487 while(i < mCurrentFrame.layerCount) {
1488 if(!mCurrentFrame.isFBComposed[i]) {
1489 if(!batchCount) {
1490 i++;
1491 break;
1492 }
1493 updatingLayersAbove++;
1494 i++;
1495 continue;
1496 } else {
1497 if(mCurrentFrame.drop[i]) {
1498 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001499 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301500 continue;
1501 } else if(updatingLayersAbove <= 0) {
1502 batchCount++;
1503 batchEnd = i;
1504 i++;
1505 continue;
1506 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1507
1508 // We have a valid updating layer already. If layer-i not
1509 // have overlapping with all updating layers in between
1510 // batch-start and i, then we can add layer i to batch.
1511 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1512 batchCount++;
1513 batchEnd = i;
1514 i++;
1515 continue;
1516 } else if(canPushBatchToTop(list, batchStart, i)) {
1517 //If All the non-updating layers with in this batch
1518 //does not have intersection with the updating layers
1519 //above in z-order, then we can safely move the batch to
1520 //higher z-order. Increment fbZ as it is moving up.
1521 if( firstZReverseIndex < 0) {
1522 firstZReverseIndex = i;
1523 }
1524 batchCount++;
1525 batchEnd = i;
1526 fbZ += updatingLayersAbove;
1527 i++;
1528 updatingLayersAbove = 0;
1529 continue;
1530 } else {
1531 //both failed.start the loop again from here.
1532 if(firstZReverseIndex >= 0) {
1533 i = firstZReverseIndex;
1534 }
1535 break;
1536 }
1537 }
1538 }
1539 }
1540 if(batchCount > maxBatchCount) {
1541 maxBatchCount = batchCount;
1542 maxBatchStart = batchStart;
1543 maxBatchEnd = batchEnd;
1544 fbZOrder = fbZ;
1545 }
1546 }
1547 return fbZOrder;
1548}
1549
1550bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1551 hwc_display_contents_1_t* list) {
1552 /* Idea is to keep as many non-updating(cached) layers in FB and
1553 * send rest of them through MDP. This is done in 2 steps.
1554 * 1. Find the maximum contiguous batch of non-updating layers.
1555 * 2. See if we can improve this batch size for caching by adding
1556 * opaque layers around the batch, if they don't have
1557 * any overlapping with the updating layers in between.
1558 * NEVER mark an updating layer for caching.
1559 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001560
1561 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001562 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301564 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001566 /* Nothing is cached. No batching needed */
1567 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001568 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001569 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001570
1571 /* No MDP comp layers, try to use other comp modes */
1572 if(mCurrentFrame.mdpCount == 0) {
1573 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001574 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001575
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301576 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001577
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301578 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001579 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001580 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001581 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301582 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001583 if(!mCurrentFrame.drop[i]){
1584 //If an unsupported layer is being attempted to
1585 //be pulled out we should fail
1586 if(not isSupportedForMDPComp(ctx, layer)) {
1587 return false;
1588 }
1589 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001590 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001591 }
1592 }
1593
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301594 // update the frame data
1595 mCurrentFrame.fbZ = fbZ;
1596 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001597 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001598 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001599
1600 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301601 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001602
1603 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001605
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001607 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001609 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001611 for(int i = 0; i < numAppLayers; i++) {
1612 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001613 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001614 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001615 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001617 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618 }
1619 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001620
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001621 frame.fbCount = fbCount;
1622 frame.mdpCount = frame.layerCount - frame.fbCount
1623 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001624
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001625 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1626 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627}
1628
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001629// drop other non-AIV layers from external display list.
1630void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001631 hwc_display_contents_1_t* list) {
1632 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1633 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001634 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001635 mCurrentFrame.dropCount++;
1636 mCurrentFrame.drop[i] = true;
1637 }
1638 }
1639 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1640 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1641 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1642 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1643 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1644 mCurrentFrame.dropCount);
1645}
1646
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001647void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001648 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001649 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1650 for(int index = 0;index < nYuvCount; index++){
1651 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1652 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1653
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001654 if(mCurrentFrame.drop[nYuvIndex]) {
1655 continue;
1656 }
1657
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001659 if(!frame.isFBComposed[nYuvIndex]) {
1660 frame.isFBComposed[nYuvIndex] = true;
1661 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 }
1663 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001664 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001665 private_handle_t *hnd = (private_handle_t *)layer->handle;
1666 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001667 frame.isFBComposed[nYuvIndex] = false;
1668 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001669 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 }
1671 }
1672 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001673
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001674 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1675 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001676}
1677
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001678void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1679 hwc_display_contents_1_t* list) {
1680 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1681 for(int index = 0;index < nSecureRGBCount; index++){
1682 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1683 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1684
1685 if(!isSecureRGBDoable(ctx, layer)) {
1686 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1687 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1688 mCurrentFrame.fbCount++;
1689 }
1690 } else {
1691 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1692 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1693 mCurrentFrame.fbCount--;
1694 }
1695 }
1696 }
1697
1698 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1699 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1700 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1701 mCurrentFrame.fbCount);
1702}
1703
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001704hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1705 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001706 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001707
1708 /* Update only the region of FB needed for composition */
1709 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1710 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1711 hwc_layer_1_t* layer = &list->hwLayers[i];
1712 hwc_rect_t dst = layer->displayFrame;
1713 fbRect = getUnion(fbRect, dst);
1714 }
1715 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001716 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001717 return fbRect;
1718}
1719
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001720bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1721 hwc_display_contents_1_t* list) {
1722
1723 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001724 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001725 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1726 return false;
1727 }
1728
1729 //Limitations checks
1730 if(!hwLimitationsCheck(ctx, list)) {
1731 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1732 return false;
1733 }
1734
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001735 //Configure framebuffer first if applicable
1736 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001737 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001738 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1739 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001740 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1741 __FUNCTION__);
1742 return false;
1743 }
1744 }
1745
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001746 mCurrentFrame.map();
1747
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001748 if(!allocLayerPipes(ctx, list)) {
1749 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001750 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001751 }
1752
1753 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001754 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001755 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001756 int mdpIndex = mCurrentFrame.layerToMDP[index];
1757 hwc_layer_1_t* layer = &list->hwLayers[index];
1758
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301759 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1760 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1761 mdpNextZOrder++;
1762 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001763 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1764 cur_pipe->zOrder = mdpNextZOrder++;
1765
radhakrishnac9a67412013-09-25 17:40:42 +05301766 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301767 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301768 if(configure4k2kYuv(ctx, layer,
1769 mCurrentFrame.mdpToLayer[mdpIndex])
1770 != 0 ){
1771 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1772 for layer %d",__FUNCTION__, index);
1773 return false;
1774 }
1775 else{
1776 mdpNextZOrder++;
1777 }
1778 continue;
1779 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001780 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1781 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301782 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001783 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001785 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001786 }
1787
Saurabh Shaha36be922013-12-16 18:18:39 -08001788 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1789 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1790 ,__FUNCTION__, mDpy);
1791 return false;
1792 }
1793
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001794 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001795 return true;
1796}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001797
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001798bool MDPComp::resourceCheck(hwc_context_t* ctx,
1799 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001800 const bool fbUsed = mCurrentFrame.fbCount;
1801 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1802 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1803 return false;
1804 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001805
1806 //Will benefit cases where a video has non-updating background.
1807 if((mDpy > HWC_DISPLAY_PRIMARY) and
1808 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1809 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1810 return false;
1811 }
1812
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001813 // Init rotCount to number of rotate sessions used by other displays
1814 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1815 // Count the number of rotator sessions required for current display
1816 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1817 if(!mCurrentFrame.isFBComposed[index]) {
1818 hwc_layer_1_t* layer = &list->hwLayers[index];
1819 private_handle_t *hnd = (private_handle_t *)layer->handle;
1820 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1821 rotCount++;
1822 }
1823 }
1824 }
1825 // if number of layers to rotate exceeds max rotator sessions, bail out.
1826 if(rotCount > RotMgr::MAX_ROT_SESS) {
1827 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1828 __FUNCTION__, mDpy);
1829 return false;
1830 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001831 return true;
1832}
1833
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301834bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1835 hwc_display_contents_1_t* list) {
1836
1837 //A-family hw limitation:
1838 //If a layer need alpha scaling, MDP can not support.
1839 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1840 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1841 if(!mCurrentFrame.isFBComposed[i] &&
1842 isAlphaScaled( &list->hwLayers[i])) {
1843 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1844 return false;
1845 }
1846 }
1847 }
1848
1849 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1850 //If multiple layers requires downscaling and also they are overlapping
1851 //fall back to GPU since MDSS can not handle it.
1852 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1853 qdutils::MDPVersion::getInstance().is8x26()) {
1854 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1855 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1856 if(!mCurrentFrame.isFBComposed[i] &&
1857 isDownscaleRequired(botLayer)) {
1858 //if layer-i is marked for MDP and needs downscaling
1859 //check if any MDP layer on top of i & overlaps with layer-i
1860 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1861 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1862 if(!mCurrentFrame.isFBComposed[j] &&
1863 isDownscaleRequired(topLayer)) {
1864 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1865 topLayer->displayFrame);
1866 if(isValidRect(r))
1867 return false;
1868 }
1869 }
1870 }
1871 }
1872 }
1873 return true;
1874}
1875
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001876int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001877 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001878 char property[PROPERTY_VALUE_MAX];
1879
Raj Kamal4393eaa2014-06-06 13:45:20 +05301880 if(!ctx || !list) {
1881 ALOGE("%s: Invalid context or list",__FUNCTION__);
1882 mCachedFrame.reset();
1883 return -1;
1884 }
1885
1886 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001887 if(mDpy == HWC_DISPLAY_PRIMARY) {
1888 sSimulationFlags = 0;
1889 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1890 int currentFlags = atoi(property);
1891 if(currentFlags != sSimulationFlags) {
1892 sSimulationFlags = currentFlags;
1893 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1894 sSimulationFlags, sSimulationFlags);
1895 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001896 }
1897 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001898 // reset PTOR
1899 if(!mDpy)
1900 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001901
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301902 //Do not cache the information for next draw cycle.
1903 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1904 ALOGI("%s: Unsupported layer count for mdp composition",
1905 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001906 mCachedFrame.reset();
1907 return -1;
1908 }
1909
Saurabh Shahb39f8152013-08-22 10:21:44 -07001910 //reset old data
1911 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001912 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1913 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301914
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001915 // Detect the start of animation and fall back to GPU only once to cache
1916 // all the layers in FB and display FB content untill animation completes.
1917 if(ctx->listStats[mDpy].isDisplayAnimating) {
1918 mCurrentFrame.needsRedraw = false;
1919 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1920 mCurrentFrame.needsRedraw = true;
1921 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1922 }
1923 setMDPCompLayerFlags(ctx, list);
1924 mCachedFrame.updateCounts(mCurrentFrame);
1925 ret = -1;
1926 return ret;
1927 } else {
1928 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1929 }
1930
Saurabh Shahb39f8152013-08-22 10:21:44 -07001931 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001932 if(isFrameDoable(ctx)) {
1933 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001934 // if AIV Video mode is enabled, drop all non AIV layers from the
1935 // external display list.
1936 if(ctx->listStats[mDpy].mAIVVideoMode) {
1937 dropNonAIVLayers(ctx, list);
1938 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001939
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001940 // if tryFullFrame fails, try to push all video and secure RGB layers
1941 // to MDP for composition.
1942 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001943 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301944 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001945 setMDPCompLayerFlags(ctx, list);
1946 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001947 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001948 reset(ctx);
1949 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1950 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001951 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001952 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1953 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001954 }
1955 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301956 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1957 enablePartialUpdateForMDP3) {
1958 generateROI(ctx, list);
1959 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1960 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1961 }
1962 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001963 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1964 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001965 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001966 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001967
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001968 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001969 ALOGD("GEOMETRY change: %d",
1970 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001971 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001972 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001973 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001974 }
1975
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001976#ifdef DYNAMIC_FPS
1977 //For primary display, set the dynamic refreshrate
Raj Kamal0d53fc62014-11-25 17:36:36 +05301978 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1979 ctx->mUseMetaDataRefreshRate) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001980 FrameInfo frame;
1981 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301982 memset(&frame.drop, 0, sizeof(frame.drop));
1983 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001984 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1985 __FUNCTION__);
1986 updateLayerCache(ctx, list, frame);
1987 updateYUV(ctx, list, false /*secure only*/, frame);
1988 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1989 //Set the new fresh rate, if there is only one updating YUV layer
1990 //or there is one single RGB layer with this request
1991 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1992 (frame.layerCount == 1)) {
1993 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1994 }
1995 setRefreshRate(ctx, mDpy, refreshRate);
1996 }
1997#endif
1998
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001999 mCachedFrame.cacheAll(list);
2000 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002001 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002002}
2003
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002004bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302005
2006 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302007 int mdpIndex = mCurrentFrame.layerToMDP[index];
2008 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2009 info.pipeInfo = new MdpYUVPipeInfo;
2010 info.rot = NULL;
2011 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302012
2013 pipe_info.lIndex = ovutils::OV_INVALID;
2014 pipe_info.rIndex = ovutils::OV_INVALID;
2015
Saurabh Shahc62f3982014-03-05 14:28:26 -08002016 Overlay::PipeSpecs pipeSpecs;
2017 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2018 pipeSpecs.needsScaling = true;
2019 pipeSpecs.dpy = mDpy;
2020 pipeSpecs.fb = false;
2021
2022 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302023 if(pipe_info.lIndex == ovutils::OV_INVALID){
2024 bRet = false;
2025 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2026 __FUNCTION__);
2027 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002028 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302029 if(pipe_info.rIndex == ovutils::OV_INVALID){
2030 bRet = false;
2031 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2032 __FUNCTION__);
2033 }
2034 return bRet;
2035}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002036
2037int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2038 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002039 if (ctx->mPtorInfo.isActive()) {
2040 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002041 if (fd < 0) {
2042 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002043 }
2044 }
2045 return fd;
2046}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002047//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002048
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002049void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302050 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002051 //If 4k2k Yuv layer split is possible, and if
2052 //fbz is above 4k2k layer, increment fb zorder by 1
2053 //as we split 4k2k layer and increment zorder for right half
2054 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002055 if(!ctx)
2056 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002057 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302058 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2059 index++) {
2060 if(!mCurrentFrame.isFBComposed[index]) {
2061 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2062 mdpNextZOrder++;
2063 }
2064 mdpNextZOrder++;
2065 hwc_layer_1_t* layer = &list->hwLayers[index];
2066 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302067 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302068 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2069 mCurrentFrame.fbZ += 1;
2070 mdpNextZOrder++;
2071 //As we split 4kx2k yuv layer and program to 2 VG pipes
2072 //(if available) increase mdpcount by 1.
2073 mCurrentFrame.mdpCount++;
2074 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002075 }
2076 }
2077 }
radhakrishnac9a67412013-09-25 17:40:42 +05302078}
2079
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002080/*
2081 * Configures pipe(s) for MDP composition
2082 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002083int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002084 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002085 MdpPipeInfoNonSplit& mdp_info =
2086 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302087 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002088 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002089 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002090
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002091 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2092 __FUNCTION__, layer, zOrder, dest);
2093
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002094 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002095 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002096}
2097
Saurabh Shah88e4d272013-09-03 13:31:29 -07002098bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002099 hwc_display_contents_1_t* list) {
2100 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002101
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002102 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002103
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002104 hwc_layer_1_t* layer = &list->hwLayers[index];
2105 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302106 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002107 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302108 continue;
2109 }
2110 }
2111
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002112 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002113 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002114 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002115 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002116 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002117
Saurabh Shahc62f3982014-03-05 14:28:26 -08002118 Overlay::PipeSpecs pipeSpecs;
2119 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2120 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2121 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2122 (qdutils::MDPVersion::getInstance().is8x26() and
2123 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2124 pipeSpecs.dpy = mDpy;
2125 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002126 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002127
Saurabh Shahc62f3982014-03-05 14:28:26 -08002128 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2129
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002130 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002131 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002132 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002133 }
2134 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002135 return true;
2136}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137
radhakrishnac9a67412013-09-25 17:40:42 +05302138int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2139 PipeLayerPair& PipeLayerPair) {
2140 MdpYUVPipeInfo& mdp_info =
2141 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2142 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302143 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302144 eDest lDest = mdp_info.lIndex;
2145 eDest rDest = mdp_info.rIndex;
2146
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002147 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302148 lDest, rDest, &PipeLayerPair.rot);
2149}
2150
Saurabh Shah88e4d272013-09-03 13:31:29 -07002151bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002152
Raj Kamal4393eaa2014-06-06 13:45:20 +05302153 if(!isEnabled() or !mModeOn) {
2154 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302155 return true;
2156 }
2157
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002158 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002159 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002160 sHandleTimeout = true;
2161 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002162
2163 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002164 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002165
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002166 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2167 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002168 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002169 if(mCurrentFrame.isFBComposed[i]) continue;
2170
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002171 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002172 private_handle_t *hnd = (private_handle_t *)layer->handle;
2173 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002174 if (!(layer->flags & HWC_COLOR_FILL)) {
2175 ALOGE("%s handle null", __FUNCTION__);
2176 return false;
2177 }
2178 // No PLAY for Color layer
2179 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2180 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002181 }
2182
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002183 int mdpIndex = mCurrentFrame.layerToMDP[i];
2184
Raj Kamal389d6e32014-08-04 14:43:24 +05302185 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302186 {
2187 MdpYUVPipeInfo& pipe_info =
2188 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2189 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2190 ovutils::eDest indexL = pipe_info.lIndex;
2191 ovutils::eDest indexR = pipe_info.rIndex;
2192 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302193 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302194 if(rot) {
2195 rot->queueBuffer(fd, offset);
2196 fd = rot->getDstMemId();
2197 offset = rot->getDstOffset();
2198 }
2199 if(indexL != ovutils::OV_INVALID) {
2200 ovutils::eDest destL = (ovutils::eDest)indexL;
2201 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2202 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2203 if (!ov.queueBuffer(fd, offset, destL)) {
2204 ALOGE("%s: queueBuffer failed for display:%d",
2205 __FUNCTION__, mDpy);
2206 return false;
2207 }
2208 }
2209
2210 if(indexR != ovutils::OV_INVALID) {
2211 ovutils::eDest destR = (ovutils::eDest)indexR;
2212 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2213 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2214 if (!ov.queueBuffer(fd, offset, destR)) {
2215 ALOGE("%s: queueBuffer failed for display:%d",
2216 __FUNCTION__, mDpy);
2217 return false;
2218 }
2219 }
2220 }
2221 else{
2222 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002223 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302224 ovutils::eDest dest = pipe_info.index;
2225 if(dest == ovutils::OV_INVALID) {
2226 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002227 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302228 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002229
radhakrishnac9a67412013-09-25 17:40:42 +05302230 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2231 continue;
2232 }
2233
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002234 int fd = hnd->fd;
2235 uint32_t offset = (uint32_t)hnd->offset;
2236 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2237 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002238 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002239 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002240 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002241 }
2242
radhakrishnac9a67412013-09-25 17:40:42 +05302243 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2244 using pipe: %d", __FUNCTION__, layer,
2245 hnd, dest );
2246
radhakrishnac9a67412013-09-25 17:40:42 +05302247 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2248 if(rot) {
2249 if(!rot->queueBuffer(fd, offset))
2250 return false;
2251 fd = rot->getDstMemId();
2252 offset = rot->getDstOffset();
2253 }
2254
2255 if (!ov.queueBuffer(fd, offset, dest)) {
2256 ALOGE("%s: queueBuffer failed for display:%d ",
2257 __FUNCTION__, mDpy);
2258 return false;
2259 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002260 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002261
2262 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002263 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002264 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002265}
2266
Saurabh Shah88e4d272013-09-03 13:31:29 -07002267//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002268
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002269void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302270 hwc_display_contents_1_t* list){
2271 //if 4kx2k yuv layer is totally present in either in left half
2272 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302273 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302274 if(mCurrentFrame.fbZ >= 0) {
2275 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2276 index++) {
2277 if(!mCurrentFrame.isFBComposed[index]) {
2278 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2279 mdpNextZOrder++;
2280 }
2281 mdpNextZOrder++;
2282 hwc_layer_1_t* layer = &list->hwLayers[index];
2283 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302284 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302285 hwc_rect_t dst = layer->displayFrame;
2286 if((dst.left > lSplit) || (dst.right < lSplit)) {
2287 mCurrentFrame.mdpCount += 1;
2288 }
2289 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2290 mCurrentFrame.fbZ += 1;
2291 mdpNextZOrder++;
2292 }
2293 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002294 }
radhakrishnac9a67412013-09-25 17:40:42 +05302295 }
2296}
2297
Saurabh Shah88e4d272013-09-03 13:31:29 -07002298bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002299 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002300
Saurabh Shahc62f3982014-03-05 14:28:26 -08002301 const int lSplit = getLeftSplit(ctx, mDpy);
2302 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002303 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002304 pipe_info.lIndex = ovutils::OV_INVALID;
2305 pipe_info.rIndex = ovutils::OV_INVALID;
2306
Saurabh Shahc62f3982014-03-05 14:28:26 -08002307 Overlay::PipeSpecs pipeSpecs;
2308 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2309 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2310 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2311 pipeSpecs.dpy = mDpy;
2312 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2313 pipeSpecs.fb = false;
2314
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002315 // Acquire pipe only for the updating half
2316 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2317 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2318
2319 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002320 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002321 if(pipe_info.lIndex == ovutils::OV_INVALID)
2322 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002323 }
2324
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002325 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002326 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2327 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002328 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002329 return false;
2330 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002331
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002332 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002333}
2334
Saurabh Shah88e4d272013-09-03 13:31:29 -07002335bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002336 hwc_display_contents_1_t* list) {
2337 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002338
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002339 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002340
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002341 hwc_layer_1_t* layer = &list->hwLayers[index];
2342 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302343 hwc_rect_t dst = layer->displayFrame;
2344 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302345 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302346 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002347 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302348 continue;
2349 }
2350 }
2351 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002352 int mdpIndex = mCurrentFrame.layerToMDP[index];
2353 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002354 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002355 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002356 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002357
Saurabh Shahc62f3982014-03-05 14:28:26 -08002358 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2359 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2360 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002361 return false;
2362 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002363 }
2364 return true;
2365}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002366
radhakrishnac9a67412013-09-25 17:40:42 +05302367int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2368 PipeLayerPair& PipeLayerPair) {
2369 const int lSplit = getLeftSplit(ctx, mDpy);
2370 hwc_rect_t dst = layer->displayFrame;
2371 if((dst.left > lSplit)||(dst.right < lSplit)){
2372 MdpYUVPipeInfo& mdp_info =
2373 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2374 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302375 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302376 eDest lDest = mdp_info.lIndex;
2377 eDest rDest = mdp_info.rIndex;
2378
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002379 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302380 lDest, rDest, &PipeLayerPair.rot);
2381 }
2382 else{
2383 return configure(ctx, layer, PipeLayerPair);
2384 }
2385}
2386
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002387/*
2388 * Configures pipe(s) for MDP composition
2389 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002390int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002391 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002392 MdpPipeInfoSplit& mdp_info =
2393 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002394 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302395 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002396 eDest lDest = mdp_info.lIndex;
2397 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002398
2399 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2400 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2401
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002402 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002403 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002404}
2405
Saurabh Shah88e4d272013-09-03 13:31:29 -07002406bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002407
Raj Kamal4393eaa2014-06-06 13:45:20 +05302408 if(!isEnabled() or !mModeOn) {
2409 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302410 return true;
2411 }
2412
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002413 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002414 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002415 sHandleTimeout = true;
2416 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002417
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002418 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002419 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002420
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002421 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2422 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002423 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002424 if(mCurrentFrame.isFBComposed[i]) continue;
2425
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002426 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002427 private_handle_t *hnd = (private_handle_t *)layer->handle;
2428 if(!hnd) {
2429 ALOGE("%s handle null", __FUNCTION__);
2430 return false;
2431 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002432
2433 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2434 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002435 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002436
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002437 int mdpIndex = mCurrentFrame.layerToMDP[i];
2438
Raj Kamal389d6e32014-08-04 14:43:24 +05302439 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302440 {
2441 MdpYUVPipeInfo& pipe_info =
2442 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2443 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2444 ovutils::eDest indexL = pipe_info.lIndex;
2445 ovutils::eDest indexR = pipe_info.rIndex;
2446 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302447 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302448 if(rot) {
2449 rot->queueBuffer(fd, offset);
2450 fd = rot->getDstMemId();
2451 offset = rot->getDstOffset();
2452 }
2453 if(indexL != ovutils::OV_INVALID) {
2454 ovutils::eDest destL = (ovutils::eDest)indexL;
2455 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2456 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2457 if (!ov.queueBuffer(fd, offset, destL)) {
2458 ALOGE("%s: queueBuffer failed for display:%d",
2459 __FUNCTION__, mDpy);
2460 return false;
2461 }
2462 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002463
radhakrishnac9a67412013-09-25 17:40:42 +05302464 if(indexR != ovutils::OV_INVALID) {
2465 ovutils::eDest destR = (ovutils::eDest)indexR;
2466 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2467 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2468 if (!ov.queueBuffer(fd, offset, destR)) {
2469 ALOGE("%s: queueBuffer failed for display:%d",
2470 __FUNCTION__, mDpy);
2471 return false;
2472 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002473 }
2474 }
radhakrishnac9a67412013-09-25 17:40:42 +05302475 else{
2476 MdpPipeInfoSplit& pipe_info =
2477 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2478 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002479
radhakrishnac9a67412013-09-25 17:40:42 +05302480 ovutils::eDest indexL = pipe_info.lIndex;
2481 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002482
radhakrishnac9a67412013-09-25 17:40:42 +05302483 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002484 uint32_t offset = (uint32_t)hnd->offset;
2485 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2486 if (!mDpy && (index != -1)) {
2487 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2488 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002489 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002490 }
radhakrishnac9a67412013-09-25 17:40:42 +05302491
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002492 if(ctx->mAD->draw(ctx, fd, offset)) {
2493 fd = ctx->mAD->getDstFd();
2494 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002495 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002496
radhakrishnac9a67412013-09-25 17:40:42 +05302497 if(rot) {
2498 rot->queueBuffer(fd, offset);
2499 fd = rot->getDstMemId();
2500 offset = rot->getDstOffset();
2501 }
2502
2503 //************* play left mixer **********
2504 if(indexL != ovutils::OV_INVALID) {
2505 ovutils::eDest destL = (ovutils::eDest)indexL;
2506 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2507 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2508 if (!ov.queueBuffer(fd, offset, destL)) {
2509 ALOGE("%s: queueBuffer failed for left mixer",
2510 __FUNCTION__);
2511 return false;
2512 }
2513 }
2514
2515 //************* play right mixer **********
2516 if(indexR != ovutils::OV_INVALID) {
2517 ovutils::eDest destR = (ovutils::eDest)indexR;
2518 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2519 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2520 if (!ov.queueBuffer(fd, offset, destR)) {
2521 ALOGE("%s: queueBuffer failed for right mixer",
2522 __FUNCTION__);
2523 return false;
2524 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002525 }
2526 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002527
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002528 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2529 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002530
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002531 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002532}
Saurabh Shahab47c692014-02-12 18:45:57 -08002533
2534//================MDPCompSrcSplit==============================================
2535bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002536 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002537 private_handle_t *hnd = (private_handle_t *)layer->handle;
2538 hwc_rect_t dst = layer->displayFrame;
2539 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2540 pipe_info.lIndex = ovutils::OV_INVALID;
2541 pipe_info.rIndex = ovutils::OV_INVALID;
2542
2543 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2544 //should have a higher priority than the right one. Pipe priorities are
2545 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002546
Saurabh Shahc62f3982014-03-05 14:28:26 -08002547 Overlay::PipeSpecs pipeSpecs;
2548 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2549 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2550 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2551 pipeSpecs.dpy = mDpy;
2552 pipeSpecs.fb = false;
2553
Saurabh Shahab47c692014-02-12 18:45:57 -08002554 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002555 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002556 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002557 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002558 }
2559
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002560 /* Use 2 pipes IF
2561 a) Layer's crop width is > 2048 or
2562 b) Layer's dest width > 2048 or
2563 c) On primary, driver has indicated with caps to split always. This is
2564 based on an empirically derived value of panel height. Applied only
2565 if the layer's width is > mixer's width
2566 */
2567
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302568 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002569 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302570 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002571 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2572 const uint32_t dstWidth = dst.right - dst.left;
2573 const uint32_t dstHeight = dst.bottom - dst.top;
2574 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002575 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002576 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2577 crop.bottom - crop.top;
2578 //Approximation to actual clock, ignoring the common factors in pipe and
2579 //mixer cases like line_time
2580 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2581 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002582
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002583 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2584 //pipe line length, we are still using 2 pipes. This is fine just because
2585 //this is source split where destination doesn't matter. Evaluate later to
2586 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002587 if(dstWidth > mdpHw.getMaxMixerWidth() or
2588 cropWidth > mdpHw.getMaxMixerWidth() or
2589 (primarySplitAlways and
2590 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002591 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002592 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002593 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002594 }
2595
2596 // Return values
2597 // 1 Left pipe is higher priority, do nothing.
2598 // 0 Pipes of same priority.
2599 //-1 Right pipe is of higher priority, needs swap.
2600 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2601 pipe_info.rIndex) == -1) {
2602 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002603 }
2604 }
2605
2606 return true;
2607}
2608
Saurabh Shahab47c692014-02-12 18:45:57 -08002609int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2610 PipeLayerPair& PipeLayerPair) {
2611 private_handle_t *hnd = (private_handle_t *)layer->handle;
2612 if(!hnd) {
2613 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2614 return -1;
2615 }
2616 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2617 MdpPipeInfoSplit& mdp_info =
2618 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2619 Rotator **rot = &PipeLayerPair.rot;
2620 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002621 eDest lDest = mdp_info.lIndex;
2622 eDest rDest = mdp_info.rIndex;
2623 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2624 hwc_rect_t dst = layer->displayFrame;
2625 int transform = layer->transform;
2626 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002627 int rotFlags = ROT_FLAGS_NONE;
2628 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2629 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2630
2631 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2632 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2633
2634 // Handle R/B swap
2635 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2636 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2637 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2638 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2639 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2640 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002641 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002642 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2643 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002644 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002645 /* Calculate the external display position based on MDP downscale,
2646 ActionSafe, and extorientation features. */
2647 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002648
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002649 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302650 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002651 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002652
2653 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2654 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002655 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002656 }
2657
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002658 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002659 (*rot) = ctx->mRotMgr->getNext();
2660 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002661 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002662 //If the video is using a single pipe, enable BWC
2663 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002664 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2665 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002666 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002667 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002668 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002669 ALOGE("%s: configRotator failed!", __FUNCTION__);
2670 return -1;
2671 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002672 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002673 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002674 }
2675
2676 //If 2 pipes being used, divide layer into half, crop and dst
2677 hwc_rect_t cropL = crop;
2678 hwc_rect_t cropR = crop;
2679 hwc_rect_t dstL = dst;
2680 hwc_rect_t dstR = dst;
2681 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2682 cropL.right = (crop.right + crop.left) / 2;
2683 cropR.left = cropL.right;
2684 sanitizeSourceCrop(cropL, cropR, hnd);
2685
Saurabh Shahb729b192014-08-15 18:04:24 -07002686 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002687 //Swap crops on H flip since 2 pipes are being used
2688 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2689 hwc_rect_t tmp = cropL;
2690 cropL = cropR;
2691 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002692 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002693 }
2694
Saurabh Shahb729b192014-08-15 18:04:24 -07002695 //cropSwap trick: If the src and dst widths are both odd, let us say
2696 //2507, then splitting both into half would cause left width to be 1253
2697 //and right 1254. If crop is swapped because of H flip, this will cause
2698 //left crop width to be 1254, whereas left dst width remains 1253, thus
2699 //inducing a scaling that is unaccounted for. To overcome that we add 1
2700 //to the dst width if there is a cropSwap. So if the original width was
2701 //2507, the left dst width will be 1254. Even if the original width was
2702 //even for ex: 2508, the left dst width will still remain 1254.
2703 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002704 dstR.left = dstL.right;
2705 }
2706
2707 //For the mdp, since either we are pre-rotating or MDP does flips
2708 orient = OVERLAY_TRANSFORM_0;
2709 transform = 0;
2710
2711 //configure left pipe
2712 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002713 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002714 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2715 (ovutils::eBlending) getBlending(layer->blending));
2716
2717 if(configMdp(ctx->mOverlay, pargL, orient,
2718 cropL, dstL, metadata, lDest) < 0) {
2719 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2720 return -1;
2721 }
2722 }
2723
2724 //configure right pipe
2725 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002726 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002727 static_cast<eRotFlags>(rotFlags),
2728 layer->planeAlpha,
2729 (ovutils::eBlending) getBlending(layer->blending));
2730 if(configMdp(ctx->mOverlay, pargR, orient,
2731 cropR, dstR, metadata, rDest) < 0) {
2732 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2733 return -1;
2734 }
2735 }
2736
2737 return 0;
2738}
2739
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002740int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2741 Locker::Autolock _l(ctx->mDrawLock);
2742 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2743 char path[MAX_SYSFS_FILE_PATH];
2744 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2745 int fd = open(path, O_WRONLY);
2746 if(fd < 0) {
2747 ALOGE("%s: Failed to open sysfd node", __FUNCTION__);
2748 return -1;
2749 }
2750 char value[4];
2751 snprintf(value, sizeof(value), "%d", (int)enable);
2752 ssize_t ret = write(fd, value, strlen(value));
2753 if(ret <= 0) {
2754 ALOGE("%s: Failed to write to sysfd nodes", __FUNCTION__);
2755 close(fd);
2756 return -1;
2757 }
2758 close(fd);
2759 sIsPartialUpdateActive = enable;
2760 return 0;
2761}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002762}; //namespace
2763