blob: 3d4e14864008d8107c9d0642c82d2e135dee7608 [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
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800195 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
196
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700197 return true;
198}
199
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800200void MDPComp::reset(hwc_context_t *ctx) {
201 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700202 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800203 ctx->mOverlay->clear(mDpy);
204 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700205}
206
Raj Kamal4393eaa2014-06-06 13:45:20 +0530207void MDPComp::reset() {
208 sHandleTimeout = false;
209 mModeOn = false;
210}
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212void MDPComp::timeout_handler(void *udata) {
213 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
214
215 if(!ctx) {
216 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
217 return;
218 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530219
220 ctx->mDrawLock.lock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800221 // Handle timeout event only if the previous composition is MDP or MIXED.
222 if(!sHandleTimeout) {
223 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530224 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800225 return;
226 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700227 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530229 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700230 return;
231 }
232 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530233 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700234 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700235 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700236}
237
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700238void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
239 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800240 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700241 if(value > maxSupported) {
242 ALOGW("%s: Input exceeds max value supported. Setting to"
243 "max value: %d", __FUNCTION__, maxSupported);
244 }
245 sMaxPipesPerMixer = min(value, maxSupported);
246}
247
Saurabh Shah59562ff2014-09-30 16:13:12 -0700248void MDPComp::setIdleTimeout(const uint32_t& timeout) {
249 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
250
251 if(sIdleInvalidator) {
252 if(timeout <= ONE_REFRESH_PERIOD_MS) {
253 //If the specified timeout is < 1 draw cycle worth, "virtually"
254 //disable idle timeout. The ideal way for clients to disable
255 //timeout is to set it to 0
256 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
257 ALOGI("Disabled idle timeout");
258 return;
259 }
260 sIdleInvalidator->setIdleTimeout(timeout);
261 ALOGI("Idle timeout set to %u", timeout);
262 } else {
263 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
264 }
265}
266
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800267void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800268 hwc_display_contents_1_t* list) {
269 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800270
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800271 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800272 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800273 if(!mCurrentFrame.isFBComposed[index]) {
274 layerProp[index].mFlags |= HWC_MDPCOMP;
275 layer->compositionType = HWC_OVERLAY;
276 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800277 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700278 /* Drop the layer when its already present in FB OR when it lies
279 * outside frame's ROI */
280 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800281 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700282 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800283 }
284 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700285}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500286
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800287void MDPComp::setRedraw(hwc_context_t *ctx,
288 hwc_display_contents_1_t* list) {
289 mCurrentFrame.needsRedraw = false;
290 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
291 (list->flags & HWC_GEOMETRY_CHANGED) ||
292 isSkipPresent(ctx, mDpy)) {
293 mCurrentFrame.needsRedraw = true;
294 }
295}
296
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800297MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700298 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700299 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800301
Saurabh Shahaa236822013-04-24 18:07:26 -0700302void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700303 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800304 if(mdpToLayer[i].pipeInfo) {
305 delete mdpToLayer[i].pipeInfo;
306 mdpToLayer[i].pipeInfo = NULL;
307 //We dont own the rotator
308 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800309 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800310 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800311
312 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
313 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700314 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315
Saurabh Shahaa236822013-04-24 18:07:26 -0700316 layerCount = numLayers;
317 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800318 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700319 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800320 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800321}
322
Saurabh Shahaa236822013-04-24 18:07:26 -0700323void MDPComp::FrameInfo::map() {
324 // populate layer and MDP maps
325 int mdpIdx = 0;
326 for(int idx = 0; idx < layerCount; idx++) {
327 if(!isFBComposed[idx]) {
328 mdpToLayer[mdpIdx].listIndex = idx;
329 layerToMDP[idx] = mdpIdx++;
330 }
331 }
332}
333
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800334MDPComp::LayerCache::LayerCache() {
335 reset();
336}
337
338void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700339 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530340 memset(&isFBComposed, true, sizeof(isFBComposed));
341 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800342 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700343}
344
345void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530346 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700347 for(int i = 0; i < numAppLayers; i++) {
348 hnd[i] = list->hwLayers[i].handle;
349 }
350}
351
352void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700353 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530354 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
355 memcpy(&drop, &curFrame.drop, sizeof(drop));
356}
357
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800358bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
359 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530360 if(layerCount != curFrame.layerCount)
361 return false;
362 for(int i = 0; i < curFrame.layerCount; i++) {
363 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
364 (curFrame.drop[i] != drop[i])) {
365 return false;
366 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800367 if(curFrame.isFBComposed[i] &&
368 (hnd[i] != list->hwLayers[i].handle)){
369 return false;
370 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530371 }
372 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800373}
374
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700375bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
376 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800377 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700378 (not isValidDimension(ctx,layer))
379 //More conditions here, SKIP, sRGB+Blend etc
380 ) {
381 return false;
382 }
383 return true;
384}
385
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530386bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800387 private_handle_t *hnd = (private_handle_t *)layer->handle;
388
389 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700390 if (layer->flags & HWC_COLOR_FILL) {
391 // Color layer
392 return true;
393 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700394 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800395 return false;
396 }
397
Naseer Ahmede850a802013-09-06 13:12:52 -0400398 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400399 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400400 return false;
401
Saurabh Shah62e1d732013-09-17 10:44:05 -0700402 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700403 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700404 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700405 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
406 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700407 int dst_w = dst.right - dst.left;
408 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800409 float w_scale = ((float)crop_w / (float)dst_w);
410 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530411 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800413 /* Workaround for MDP HW limitation in DSI command mode panels where
414 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
415 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530416 * There also is a HW limilation in MDP, minimum block size is 2x2
417 * Fallback to GPU if height is less than 2.
418 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700419 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800420 return false;
421
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800422 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530423 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800424 const float w_dscale = w_scale;
425 const float h_dscale = h_scale;
426
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800427 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700428
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530429 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700430 /* On targets that doesnt support Decimation (eg.,8x26)
431 * maximum downscale support is overlay pipe downscale.
432 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800433 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530434 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700435 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800436 return false;
437 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700438 // Decimation on macrotile format layers is not supported.
439 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530440 /* Bail out if
441 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700442 * 2. exceeds maximum downscale limit
443 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800444 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530445 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700446 w_dscale > maxMDPDownscale ||
447 h_dscale > maxMDPDownscale) {
448 return false;
449 }
450 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800451 return false;
452 }
453 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700454 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700455 return false;
456 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700457 }
458
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800459 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530460 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800461 const float w_uscale = 1.0f / w_scale;
462 const float h_uscale = 1.0f / h_scale;
463
464 if(w_uscale > upscale || h_uscale > upscale)
465 return false;
466 }
467
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800468 return true;
469}
470
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800471bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700472 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800473
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800474 if(!isEnabled()) {
475 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700476 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530477 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530478 qdutils::MDPVersion::getInstance().is8x16() ||
479 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800480 ctx->mVideoTransFlag &&
481 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700482 //1 Padding round to shift pipes across mixers
483 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
484 __FUNCTION__);
485 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700486 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
487 /* TODO: freeing up all the resources only for the targets having total
488 number of pipes < 8. Need to analyze number of VIG pipes used
489 for primary in previous draw cycle and accordingly decide
490 whether to fall back to full GPU comp or video only comp
491 */
492 if(isSecondaryConfiguring(ctx)) {
493 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
494 __FUNCTION__);
495 ret = false;
496 } else if(ctx->isPaddingRound) {
497 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
498 __FUNCTION__,mDpy);
499 ret = false;
500 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800501 } else if (ctx->isDMAStateChanging) {
502 // Bail out if a padding round has been invoked in order to switch DMA
503 // state to block mode. We need this to cater for the case when a layer
504 // requires rotation in the current frame.
505 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
506 __FUNCTION__);
507 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700508 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800509
Saurabh Shahaa236822013-04-24 18:07:26 -0700510 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800511}
512
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800513void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
514 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
515 fbRect = getIntersection(fbRect, roi);
516}
517
518/* 1) Identify layers that are not visible or lying outside the updating ROI and
519 * drop them from composition.
520 * 2) If we have a scaling layer which needs cropping against generated
521 * ROI, reset ROI to full resolution. */
522bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
523 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700524 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800525 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800526
527 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800528 if(!isValidRect(visibleRect)) {
529 mCurrentFrame.drop[i] = true;
530 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800531 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800532 }
533
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700535 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800536 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700537
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700538 if(!isValidRect(res)) {
539 mCurrentFrame.drop[i] = true;
540 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800541 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700542 /* Reset frame ROI when any layer which needs scaling also needs ROI
543 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800544 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800545 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700546 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
547 mCurrentFrame.dropCount = 0;
548 return false;
549 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800550
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800551 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530552 if (layer->blending == HWC_BLENDING_NONE &&
553 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800554 visibleRect = deductRect(visibleRect, res);
555 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700556 }
557 return true;
558}
559
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800560/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
561 * are updating. If DirtyRegion is applicable, calculate it by accounting all
562 * the changing layer's dirtyRegion. */
563void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
564 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700565 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800566 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700567 return;
568
569 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800570 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
571 (int)ctx->dpyAttr[mDpy].yres};
572
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700573 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800574 hwc_layer_1_t* layer = &list->hwLayers[index];
575 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800576 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700577 hwc_rect_t dst = layer->displayFrame;
578 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800579
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800580#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800581 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700582 {
583 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
584 int x_off = dst.left - src.left;
585 int y_off = dst.top - src.top;
586 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
587 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800588#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800589
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800590 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700591 }
592 }
593
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800594 /* No layer is updating. Still SF wants a refresh.*/
595 if(!isValidRect(roi))
596 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800597
598 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800599 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800600
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800601 ctx->listStats[mDpy].lRoi = roi;
602 if(!validateAndApplyROI(ctx, list))
603 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700604
605 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800606 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
607 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
608}
609
610void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
611 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
612 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
613
614 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
615 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
616 fbRect = getUnion(l_fbRect, r_fbRect);
617}
618/* 1) Identify layers that are not visible or lying outside BOTH the updating
619 * ROI's and drop them from composition. If a layer is spanning across both
620 * the halves of the screen but needed by only ROI, the non-contributing
621 * half will not be programmed for MDP.
622 * 2) If we have a scaling layer which needs cropping against generated
623 * ROI, reset ROI to full resolution. */
624bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
625 hwc_display_contents_1_t* list) {
626
627 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
628
629 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
630 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
631
632 for(int i = numAppLayers - 1; i >= 0; i--){
633 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
634 {
635 mCurrentFrame.drop[i] = true;
636 mCurrentFrame.dropCount++;
637 continue;
638 }
639
640 const hwc_layer_1_t* layer = &list->hwLayers[i];
641 hwc_rect_t dstRect = layer->displayFrame;
642
643 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
644 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
645 hwc_rect_t res = getUnion(l_res, r_res);
646
647 if(!isValidRect(l_res) && !isValidRect(r_res)) {
648 mCurrentFrame.drop[i] = true;
649 mCurrentFrame.dropCount++;
650 } else {
651 /* Reset frame ROI when any layer which needs scaling also needs ROI
652 * cropping */
653 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
654 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
655 mCurrentFrame.dropCount = 0;
656 return false;
657 }
658
radhakrishna4efbdd62014-11-03 13:19:27 +0530659 if (layer->blending == HWC_BLENDING_NONE &&
660 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800661 visibleRectL = deductRect(visibleRectL, l_res);
662 visibleRectR = deductRect(visibleRectR, r_res);
663 }
664 }
665 }
666 return true;
667}
668/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
669 * are updating. If DirtyRegion is applicable, calculate it by accounting all
670 * the changing layer's dirtyRegion. */
671void MDPCompSplit::generateROI(hwc_context_t *ctx,
672 hwc_display_contents_1_t* list) {
673 if(!canPartialUpdate(ctx, list))
674 return;
675
676 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
677 int lSplit = getLeftSplit(ctx, mDpy);
678
679 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
680 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
681
682 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
683 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
684
685 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
686 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
687
688 for(int index = 0; index < numAppLayers; index++ ) {
689 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800690 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800691 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800692 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700693 hwc_rect_t dst = layer->displayFrame;
694 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800695
696#ifdef QCOM_BSP
697 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700698 {
699 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
700 int x_off = dst.left - src.left;
701 int y_off = dst.top - src.top;
702 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
703 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800704#endif
705
706 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
707 if(isValidRect(l_dst))
708 l_roi = getUnion(l_roi, l_dst);
709
710 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
711 if(isValidRect(r_dst))
712 r_roi = getUnion(r_roi, r_dst);
713 }
714 }
715
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700716 /* For panels that cannot accept commands in both the interfaces, we cannot
717 * send two ROI's (for each half). We merge them into single ROI and split
718 * them across lSplit for MDP mixer use. The ROI's will be merged again
719 * finally before udpating the panel in the driver. */
720 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
721 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
722 l_roi = getIntersection(temp_roi, l_frame);
723 r_roi = getIntersection(temp_roi, r_frame);
724 }
725
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800726 /* No layer is updating. Still SF wants a refresh. */
727 if(!isValidRect(l_roi) && !isValidRect(r_roi))
728 return;
729
730 l_roi = getSanitizeROI(l_roi, l_frame);
731 r_roi = getSanitizeROI(r_roi, r_frame);
732
733 ctx->listStats[mDpy].lRoi = l_roi;
734 ctx->listStats[mDpy].rRoi = r_roi;
735
736 if(!validateAndApplyROI(ctx, list))
737 resetROI(ctx, mDpy);
738
739 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
740 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
741 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
742 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
743 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
744 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700745}
746
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800747/* Checks for conditions where all the layers marked for MDP comp cannot be
748 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800749bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800750 hwc_display_contents_1_t* list){
751
Saurabh Shahaa236822013-04-24 18:07:26 -0700752 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800753
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700754 // Fall back to video only composition, if AIV video mode is enabled
755 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700756 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
757 __FUNCTION__, mDpy);
758 return false;
759 }
760
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530761 /* No Idle fall back if secure display or secure RGB layers are present
762 * or if there is only a single layer being composed */
763 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
764 !ctx->listStats[mDpy].secureRGBCount &&
765 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700766 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
767 return false;
768 }
769
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800770 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700771 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
772 __FUNCTION__,
773 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800774 return false;
775 }
776
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700777 // if secondary is configuring or Padding round, fall back to video only
778 // composition and release all assigned non VIG pipes from primary.
779 if(isSecondaryConfiguring(ctx)) {
780 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
781 __FUNCTION__);
782 return false;
783 } else if(ctx->isPaddingRound) {
784 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
785 __FUNCTION__,mDpy);
786 return false;
787 }
788
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700789 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800790 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700791 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800792 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
793 return false;
794 }
795
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800796 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800797 hwc_layer_1_t* layer = &list->hwLayers[i];
798 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800799
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800800 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700801 if(!canUseRotator(ctx, mDpy)) {
802 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
803 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700804 return false;
805 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800806 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530807
808 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
809 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800810 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700811 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530812 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
813 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
814 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800815 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700816
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700817 if(ctx->mAD->isDoable()) {
818 return false;
819 }
820
Saurabh Shahaa236822013-04-24 18:07:26 -0700821 //If all above hard conditions are met we can do full or partial MDP comp.
822 bool ret = false;
823 if(fullMDPComp(ctx, list)) {
824 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700825 } else if(fullMDPCompWithPTOR(ctx, list)) {
826 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700827 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700828 ret = true;
829 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530830
Saurabh Shahaa236822013-04-24 18:07:26 -0700831 return ret;
832}
833
834bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700835
836 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
837 return false;
838
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700839 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
840 for(int i = 0; i < numAppLayers; i++) {
841 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700842 if(not mCurrentFrame.drop[i] and
843 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700844 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
845 return false;
846 }
847 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800848
Saurabh Shahaa236822013-04-24 18:07:26 -0700849 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700850 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
851 sizeof(mCurrentFrame.isFBComposed));
852 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
853 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700854
Raj Kamal389d6e32014-08-04 14:43:24 +0530855 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800856 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530857 }
858
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800859 if(!postHeuristicsHandling(ctx, list)) {
860 ALOGD_IF(isDebug(), "post heuristic handling failed");
861 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700862 return false;
863 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700864 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
865 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700866 return true;
867}
868
Sushil Chauhandefd3522014-05-13 18:17:12 -0700869/* Full MDP Composition with Peripheral Tiny Overlap Removal.
870 * MDP bandwidth limitations can be avoided, if the overlap region
871 * covered by the smallest layer at a higher z-order, gets composed
872 * by Copybit on a render buffer, which can be queued to MDP.
873 */
874bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
875 hwc_display_contents_1_t* list) {
876
877 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
878 const int stagesForMDP = min(sMaxPipesPerMixer,
879 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
880
881 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700882 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700883 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
884 return false;
885 }
886
887 // Frame level checks
888 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
889 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
890 isSecurePresent(ctx, mDpy)) {
891 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
892 return false;
893 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700894 // MDP comp checks
895 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700896 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700897 if(not isSupportedForMDPComp(ctx, layer)) {
898 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
899 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700900 }
901 }
902
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 /* We cannot use this composition mode, if:
904 1. A below layer needs scaling.
905 2. Overlap is not peripheral to display.
906 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700907 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700908 */
909
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
911 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
912 memset(overlapRect, 0, sizeof(overlapRect));
913 int layerPixelCount, minPixelCount = 0;
914 int numPTORLayersFound = 0;
915 for (int i = numAppLayers-1; (i >= 0 &&
916 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700917 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700919 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700920 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
921 // PTOR layer should be peripheral and cannot have transform
922 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
923 has90Transform(layer)) {
924 continue;
925 }
926 if((3 * (layerPixelCount + minPixelCount)) >
927 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
928 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
929 continue;
930 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700931 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700932 for (int j = i-1; j >= 0; j--) {
933 // Check if the layers below this layer qualifies for PTOR comp
934 hwc_layer_1_t* layer = &list->hwLayers[j];
935 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700936 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700937 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700938 if (isValidRect(getIntersection(dispFrame, disFrame))) {
939 if (has90Transform(layer) || needsScaling(layer)) {
940 found = false;
941 break;
942 }
943 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 }
945 }
946 // Store the minLayer Index
947 if(found) {
948 minLayerIndex[numPTORLayersFound] = i;
949 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
950 minPixelCount += layerPixelCount;
951 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700952 }
953 }
954
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700955 // No overlap layers
956 if (!numPTORLayersFound)
957 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700958
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700959 // Store the displayFrame and the sourceCrops of the layers
960 hwc_rect_t displayFrame[numAppLayers];
961 hwc_rect_t sourceCrop[numAppLayers];
962 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700963 hwc_layer_1_t* layer = &list->hwLayers[i];
964 displayFrame[i] = layer->displayFrame;
965 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700966 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700967
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530968 /**
969 * It's possible that 2 PTOR layers might have overlapping.
970 * In such case, remove the intersection(again if peripheral)
971 * from the lower PTOR layer to avoid overlapping.
972 * If intersection is not on peripheral then compromise
973 * by reducing number of PTOR layers.
974 **/
975 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
976 if(isValidRect(commonRect)) {
977 overlapRect[1] = deductRect(overlapRect[1], commonRect);
978 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
979 }
980
981 ctx->mPtorInfo.count = numPTORLayersFound;
982 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
983 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
984 }
985
986 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
987 // reset PTOR
988 ctx->mPtorInfo.count = 0;
989 if(isValidRect(commonRect)) {
990 // If PTORs are intersecting restore displayframe of PTOR[1]
991 // before returning, as we have modified it above.
992 list->hwLayers[minLayerIndex[1]].displayFrame =
993 displayFrame[minLayerIndex[1]];
994 }
995 return false;
996 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700997 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
998 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
999
Xu Yangcda012c2014-07-30 21:57:21 +08001000 // Store the blending mode, planeAlpha, and transform of PTOR layers
1001 int32_t blending[numPTORLayersFound];
1002 uint8_t planeAlpha[numPTORLayersFound];
1003 uint32_t transform[numPTORLayersFound];
1004
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001005 for(int j = 0; j < numPTORLayersFound; j++) {
1006 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001007
1008 // Update src crop of PTOR layer
1009 hwc_layer_1_t* layer = &list->hwLayers[index];
1010 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1011 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1012 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1013 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1014
1015 // Store & update w, h, format of PTOR layer
1016 private_handle_t *hnd = (private_handle_t *)layer->handle;
1017 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1018 layerWhf[j] = whf;
1019 hnd->width = renderBuf->width;
1020 hnd->height = renderBuf->height;
1021 hnd->format = renderBuf->format;
1022
Xu Yangcda012c2014-07-30 21:57:21 +08001023 // Store & update blending mode, planeAlpha and transform of PTOR layer
1024 blending[j] = layer->blending;
1025 planeAlpha[j] = layer->planeAlpha;
1026 transform[j] = layer->transform;
1027 layer->blending = HWC_BLENDING_NONE;
1028 layer->planeAlpha = 0xFF;
1029 layer->transform = 0;
1030
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001031 // Remove overlap from crop & displayFrame of below layers
1032 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001033 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001034 if(!isValidRect(getIntersection(layer->displayFrame,
1035 overlapRect[j]))) {
1036 continue;
1037 }
1038 // Update layer attributes
1039 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1040 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301041 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001042 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1043 layer->transform);
1044 layer->sourceCropf.left = (float)srcCrop.left;
1045 layer->sourceCropf.top = (float)srcCrop.top;
1046 layer->sourceCropf.right = (float)srcCrop.right;
1047 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1048 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001049 }
1050
1051 mCurrentFrame.mdpCount = numAppLayers;
1052 mCurrentFrame.fbCount = 0;
1053 mCurrentFrame.fbZ = -1;
1054
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301055 for (int j = 0; j < numAppLayers; j++) {
1056 if(isValidRect(list->hwLayers[j].displayFrame)) {
1057 mCurrentFrame.isFBComposed[j] = false;
1058 } else {
1059 mCurrentFrame.mdpCount--;
1060 mCurrentFrame.drop[j] = true;
1061 }
1062 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001063
1064 bool result = postHeuristicsHandling(ctx, list);
1065
1066 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001067 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001068 hwc_layer_1_t* layer = &list->hwLayers[i];
1069 layer->displayFrame = displayFrame[i];
1070 layer->sourceCropf.left = (float)sourceCrop[i].left;
1071 layer->sourceCropf.top = (float)sourceCrop[i].top;
1072 layer->sourceCropf.right = (float)sourceCrop[i].right;
1073 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1074 }
1075
Xu Yangcda012c2014-07-30 21:57:21 +08001076 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001077 for (int i = 0; i < numPTORLayersFound; i++) {
1078 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001079 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001080 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1081 hnd->width = layerWhf[i].w;
1082 hnd->height = layerWhf[i].h;
1083 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001084 layer->blending = blending[i];
1085 layer->planeAlpha = planeAlpha[i];
1086 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001087 }
1088
Sushil Chauhandefd3522014-05-13 18:17:12 -07001089 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001090 // reset PTOR
1091 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001092 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001093 } else {
1094 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1095 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001096 }
1097
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001098 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1099 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001100 return result;
1101}
1102
Saurabh Shahaa236822013-04-24 18:07:26 -07001103bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1104{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001105 if(!sEnableMixedMode) {
1106 //Mixed mode is disabled. No need to even try caching.
1107 return false;
1108 }
1109
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001110 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001111 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001112 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001113 cacheBasedComp(ctx, list);
1114 } else {
1115 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001116 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001117 }
1118
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001119 return ret;
1120}
1121
1122bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1123 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001124 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1125 return false;
1126
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001127 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001128 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001129 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001130
1131 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1132 for(int i = 0; i < numAppLayers; i++) {
1133 if(!mCurrentFrame.isFBComposed[i]) {
1134 hwc_layer_1_t* layer = &list->hwLayers[i];
1135 if(not isSupportedForMDPComp(ctx, layer)) {
1136 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1137 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001138 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001139 return false;
1140 }
1141 }
1142 }
1143
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001144 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001145 /* mark secure RGB layers for MDP comp */
1146 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301147 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001148 if(!ret) {
1149 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001150 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001151 return false;
1152 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001153
1154 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001155
Raj Kamal389d6e32014-08-04 14:43:24 +05301156 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001157 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301158 }
1159
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001160 if(!postHeuristicsHandling(ctx, list)) {
1161 ALOGD_IF(isDebug(), "post heuristic handling failed");
1162 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001163 return false;
1164 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001165 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1166 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001167
Saurabh Shahaa236822013-04-24 18:07:26 -07001168 return true;
1169}
1170
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001171bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001172 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001173 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1174 return false;
1175
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001176 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001177 return false;
1178 }
1179
Saurabh Shahb772ae32013-11-18 15:40:02 -08001180 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001181 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1182 const int stagesForMDP = min(sMaxPipesPerMixer,
1183 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001184
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001185 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1186 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1187 int lastMDPSupportedIndex = numAppLayers;
1188 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001189
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001190 //Find the minimum MDP batch size
1191 for(int i = 0; i < numAppLayers;i++) {
1192 if(mCurrentFrame.drop[i]) {
1193 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001194 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001195 }
1196 hwc_layer_1_t* layer = &list->hwLayers[i];
1197 if(not isSupportedForMDPComp(ctx, layer)) {
1198 lastMDPSupportedIndex = i;
1199 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1200 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001201 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001202 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001203 }
1204
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001205 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1206 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1207 mCurrentFrame.dropCount);
1208
1209 //Start at a point where the fb batch should at least have 2 layers, for
1210 //this mode to be justified.
1211 while(fbBatchSize < 2) {
1212 ++fbBatchSize;
1213 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001214 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001215
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001216 //If there are no layers for MDP, this mode doesnt make sense.
1217 if(mdpBatchSize < 1) {
1218 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1219 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001220 return false;
1221 }
1222
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001223 mCurrentFrame.reset(numAppLayers);
1224
1225 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1226 while(mdpBatchSize > 0) {
1227 //Mark layers for MDP comp
1228 int mdpBatchLeft = mdpBatchSize;
1229 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1230 if(mCurrentFrame.drop[i]) {
1231 continue;
1232 }
1233 mCurrentFrame.isFBComposed[i] = false;
1234 --mdpBatchLeft;
1235 }
1236
1237 mCurrentFrame.fbZ = mdpBatchSize;
1238 mCurrentFrame.fbCount = fbBatchSize;
1239 mCurrentFrame.mdpCount = mdpBatchSize;
1240
1241 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1242 __FUNCTION__, mdpBatchSize, fbBatchSize,
1243 mCurrentFrame.dropCount);
1244
1245 if(postHeuristicsHandling(ctx, list)) {
1246 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001247 __FUNCTION__);
1248 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1249 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001250 return true;
1251 }
1252
1253 reset(ctx);
1254 --mdpBatchSize;
1255 ++fbBatchSize;
1256 }
1257
1258 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001259}
1260
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001261bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301262 if(mDpy or isSecurePresent(ctx, mDpy) or
1263 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001264 return false;
1265 }
1266 return true;
1267}
1268
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001269bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1270 hwc_display_contents_1_t* list){
1271 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1272 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001273 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001274 return false;
1275 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001276 if(ctx->listStats[mDpy].secureUI)
1277 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001278 return true;
1279}
1280
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001281bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1282 hwc_display_contents_1_t* list) {
1283 const bool secureOnly = true;
1284 return videoOnlyComp(ctx, list, not secureOnly) or
1285 videoOnlyComp(ctx, list, secureOnly);
1286}
1287
1288bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001289 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001290 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1291 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301292
Saurabh Shahaa236822013-04-24 18:07:26 -07001293 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301294 if(!isSecurePresent(ctx, mDpy)) {
1295 /* Bail out if we are processing only secured video layers
1296 * and we dont have any */
1297 if(secureOnly) {
1298 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1299 return false;
1300 }
1301 /* No Idle fall back for secure video layers and if there is only
1302 * single layer being composed. */
1303 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1304 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1305 return false;
1306 }
1307 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001308
Saurabh Shahaa236822013-04-24 18:07:26 -07001309 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001310 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001311 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001312 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001313
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001314 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1315 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001316 return false;
1317 }
1318
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001319 if(mCurrentFrame.fbCount)
1320 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001321
Raj Kamal389d6e32014-08-04 14:43:24 +05301322 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001323 adjustForSourceSplit(ctx, list);
1324 }
1325
1326 if(!postHeuristicsHandling(ctx, list)) {
1327 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301328 if(errno == ENOBUFS) {
1329 ALOGD_IF(isDebug(), "SMP Allocation failed");
1330 //On SMP allocation failure in video only comp add padding round
1331 ctx->isPaddingRound = true;
1332 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001333 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001334 return false;
1335 }
1336
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001337 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1338 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001339 return true;
1340}
1341
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001342/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1343bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1344 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001345 // Fall back to video only composition, if AIV video mode is enabled
1346 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001347 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1348 __FUNCTION__, mDpy);
1349 return false;
1350 }
1351
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001352 const bool secureOnly = true;
1353 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1354 mdpOnlyLayersComp(ctx, list, secureOnly);
1355
1356}
1357
1358bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1359 hwc_display_contents_1_t* list, bool secureOnly) {
1360
1361 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1362 return false;
1363
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301364 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1365 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1366 /* Bail out if we are processing only secured video/ui layers
1367 * and we dont have any */
1368 if(secureOnly) {
1369 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1370 return false;
1371 }
1372 /* No Idle fall back for secure video/ui layers and if there is only
1373 * single layer being composed. */
1374 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1375 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1376 return false;
1377 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001378 }
1379
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001380 mCurrentFrame.reset(numAppLayers);
1381 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1382
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001383 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001384 /* mark secure RGB layers for MDP comp */
1385 updateSecureRGB(ctx, list);
1386
1387 if(mCurrentFrame.mdpCount == 0) {
1388 reset(ctx);
1389 return false;
1390 }
1391
1392 /* find the maximum batch of layers to be marked for framebuffer */
1393 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1394 if(!ret) {
1395 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1396 reset(ctx);
1397 return false;
1398 }
1399
1400 if(sEnableYUVsplit){
1401 adjustForSourceSplit(ctx, list);
1402 }
1403
1404 if(!postHeuristicsHandling(ctx, list)) {
1405 ALOGD_IF(isDebug(), "post heuristic handling failed");
1406 reset(ctx);
1407 return false;
1408 }
1409
1410 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1411 __FUNCTION__);
1412 return true;
1413}
1414
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001415/* Checks for conditions where YUV layers cannot be bypassed */
1416bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001417 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001418 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001419 return false;
1420 }
1421
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001422 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001423 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1424 return false;
1425 }
1426
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001427 if(isSecuring(ctx, layer)) {
1428 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1429 return false;
1430 }
1431
Saurabh Shah4fdde762013-04-30 18:47:33 -07001432 if(!isValidDimension(ctx, layer)) {
1433 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1434 __FUNCTION__);
1435 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001436 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001437
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001438 if(layer->planeAlpha < 0xFF) {
1439 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1440 in video only mode",
1441 __FUNCTION__);
1442 return false;
1443 }
1444
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001445 return true;
1446}
1447
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001448/* Checks for conditions where Secure RGB layers cannot be bypassed */
1449bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1450 if(isSkipLayer(layer)) {
1451 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1452 __FUNCTION__, mDpy);
1453 return false;
1454 }
1455
1456 if(isSecuring(ctx, layer)) {
1457 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1458 return false;
1459 }
1460
1461 if(not isSupportedForMDPComp(ctx, layer)) {
1462 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1463 __FUNCTION__);
1464 return false;
1465 }
1466 return true;
1467}
1468
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301469/* starts at fromIndex and check for each layer to find
1470 * if it it has overlapping with any Updating layer above it in zorder
1471 * till the end of the batch. returns true if it finds any intersection */
1472bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1473 int fromIndex, int toIndex) {
1474 for(int i = fromIndex; i < toIndex; i++) {
1475 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1476 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1477 return false;
1478 }
1479 }
1480 }
1481 return true;
1482}
1483
1484/* Checks if given layer at targetLayerIndex has any
1485 * intersection with all the updating layers in beween
1486 * fromIndex and toIndex. Returns true if it finds intersectiion */
1487bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1488 int fromIndex, int toIndex, int targetLayerIndex) {
1489 for(int i = fromIndex; i <= toIndex; i++) {
1490 if(!mCurrentFrame.isFBComposed[i]) {
1491 if(areLayersIntersecting(&list->hwLayers[i],
1492 &list->hwLayers[targetLayerIndex])) {
1493 return true;
1494 }
1495 }
1496 }
1497 return false;
1498}
1499
1500int MDPComp::getBatch(hwc_display_contents_1_t* list,
1501 int& maxBatchStart, int& maxBatchEnd,
1502 int& maxBatchCount) {
1503 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301504 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001505 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301506 while (i < mCurrentFrame.layerCount) {
1507 int batchCount = 0;
1508 int batchStart = i;
1509 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001510 /* Adjust batch Z order with the dropped layers so far */
1511 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301512 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301513 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301514 while(i < mCurrentFrame.layerCount) {
1515 if(!mCurrentFrame.isFBComposed[i]) {
1516 if(!batchCount) {
1517 i++;
1518 break;
1519 }
1520 updatingLayersAbove++;
1521 i++;
1522 continue;
1523 } else {
1524 if(mCurrentFrame.drop[i]) {
1525 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001526 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301527 continue;
1528 } else if(updatingLayersAbove <= 0) {
1529 batchCount++;
1530 batchEnd = i;
1531 i++;
1532 continue;
1533 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1534
1535 // We have a valid updating layer already. If layer-i not
1536 // have overlapping with all updating layers in between
1537 // batch-start and i, then we can add layer i to batch.
1538 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1539 batchCount++;
1540 batchEnd = i;
1541 i++;
1542 continue;
1543 } else if(canPushBatchToTop(list, batchStart, i)) {
1544 //If All the non-updating layers with in this batch
1545 //does not have intersection with the updating layers
1546 //above in z-order, then we can safely move the batch to
1547 //higher z-order. Increment fbZ as it is moving up.
1548 if( firstZReverseIndex < 0) {
1549 firstZReverseIndex = i;
1550 }
1551 batchCount++;
1552 batchEnd = i;
1553 fbZ += updatingLayersAbove;
1554 i++;
1555 updatingLayersAbove = 0;
1556 continue;
1557 } else {
1558 //both failed.start the loop again from here.
1559 if(firstZReverseIndex >= 0) {
1560 i = firstZReverseIndex;
1561 }
1562 break;
1563 }
1564 }
1565 }
1566 }
1567 if(batchCount > maxBatchCount) {
1568 maxBatchCount = batchCount;
1569 maxBatchStart = batchStart;
1570 maxBatchEnd = batchEnd;
1571 fbZOrder = fbZ;
1572 }
1573 }
1574 return fbZOrder;
1575}
1576
1577bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1578 hwc_display_contents_1_t* list) {
1579 /* Idea is to keep as many non-updating(cached) layers in FB and
1580 * send rest of them through MDP. This is done in 2 steps.
1581 * 1. Find the maximum contiguous batch of non-updating layers.
1582 * 2. See if we can improve this batch size for caching by adding
1583 * opaque layers around the batch, if they don't have
1584 * any overlapping with the updating layers in between.
1585 * NEVER mark an updating layer for caching.
1586 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001587
1588 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001589 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001590 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301591 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001592
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001593 /* Nothing is cached. No batching needed */
1594 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001595 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001596 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001597
1598 /* No MDP comp layers, try to use other comp modes */
1599 if(mCurrentFrame.mdpCount == 0) {
1600 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001601 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301603 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001604
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301605 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001607 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001608 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301609 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001610 if(!mCurrentFrame.drop[i]){
1611 //If an unsupported layer is being attempted to
1612 //be pulled out we should fail
1613 if(not isSupportedForMDPComp(ctx, layer)) {
1614 return false;
1615 }
1616 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001617 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618 }
1619 }
1620
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301621 // update the frame data
1622 mCurrentFrame.fbZ = fbZ;
1623 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001624 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001625 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626
1627 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301628 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001629
1630 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001631}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001632
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001633void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001634 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001635 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001636 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001637
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001638 for(int i = 0; i < numAppLayers; i++) {
1639 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001640 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001641 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001642 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001644 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001645 }
1646 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001647
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001648 frame.fbCount = fbCount;
1649 frame.mdpCount = frame.layerCount - frame.fbCount
1650 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001651
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001652 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1653 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001654}
1655
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001656// drop other non-AIV layers from external display list.
1657void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001658 hwc_display_contents_1_t* list) {
1659 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1660 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001661 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001662 mCurrentFrame.dropCount++;
1663 mCurrentFrame.drop[i] = true;
1664 }
1665 }
1666 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1667 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1668 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1669 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1670 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1671 mCurrentFrame.dropCount);
1672}
1673
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001674void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001675 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001676 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1677 for(int index = 0;index < nYuvCount; index++){
1678 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1679 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1680
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001681 if(mCurrentFrame.drop[nYuvIndex]) {
1682 continue;
1683 }
1684
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001685 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001686 if(!frame.isFBComposed[nYuvIndex]) {
1687 frame.isFBComposed[nYuvIndex] = true;
1688 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001689 }
1690 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001691 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001692 private_handle_t *hnd = (private_handle_t *)layer->handle;
1693 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001694 frame.isFBComposed[nYuvIndex] = false;
1695 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001696 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001697 }
1698 }
1699 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001700
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001701 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1702 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001703}
1704
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001705void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1706 hwc_display_contents_1_t* list) {
1707 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1708 for(int index = 0;index < nSecureRGBCount; index++){
1709 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1710 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1711
1712 if(!isSecureRGBDoable(ctx, layer)) {
1713 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1714 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1715 mCurrentFrame.fbCount++;
1716 }
1717 } else {
1718 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1719 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1720 mCurrentFrame.fbCount--;
1721 }
1722 }
1723 }
1724
1725 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1726 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1727 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1728 mCurrentFrame.fbCount);
1729}
1730
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001731hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1732 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001733 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001734
1735 /* Update only the region of FB needed for composition */
1736 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1737 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1738 hwc_layer_1_t* layer = &list->hwLayers[i];
1739 hwc_rect_t dst = layer->displayFrame;
1740 fbRect = getUnion(fbRect, dst);
1741 }
1742 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001743 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001744 return fbRect;
1745}
1746
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001747bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1748 hwc_display_contents_1_t* list) {
1749
1750 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001751 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001752 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1753 return false;
1754 }
1755
1756 //Limitations checks
1757 if(!hwLimitationsCheck(ctx, list)) {
1758 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1759 return false;
1760 }
1761
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001762 //Configure framebuffer first if applicable
1763 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001764 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001765 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1766 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001767 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1768 __FUNCTION__);
1769 return false;
1770 }
1771 }
1772
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001773 mCurrentFrame.map();
1774
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001775 if(!allocLayerPipes(ctx, list)) {
1776 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001777 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001778 }
1779
1780 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001781 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001782 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001783 int mdpIndex = mCurrentFrame.layerToMDP[index];
1784 hwc_layer_1_t* layer = &list->hwLayers[index];
1785
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301786 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1787 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1788 mdpNextZOrder++;
1789 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001790 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1791 cur_pipe->zOrder = mdpNextZOrder++;
1792
radhakrishnac9a67412013-09-25 17:40:42 +05301793 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301794 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301795 if(configure4k2kYuv(ctx, layer,
1796 mCurrentFrame.mdpToLayer[mdpIndex])
1797 != 0 ){
1798 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1799 for layer %d",__FUNCTION__, index);
1800 return false;
1801 }
1802 else{
1803 mdpNextZOrder++;
1804 }
1805 continue;
1806 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001807 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1808 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301809 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001810 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001811 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001812 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001813 }
1814
Saurabh Shaha36be922013-12-16 18:18:39 -08001815 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1816 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1817 ,__FUNCTION__, mDpy);
1818 return false;
1819 }
1820
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001821 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001822 return true;
1823}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001824
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001825bool MDPComp::resourceCheck(hwc_context_t* ctx,
1826 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001827 const bool fbUsed = mCurrentFrame.fbCount;
1828 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1829 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1830 return false;
1831 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001832
1833 //Will benefit cases where a video has non-updating background.
1834 if((mDpy > HWC_DISPLAY_PRIMARY) and
1835 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1836 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1837 return false;
1838 }
1839
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001840 // Init rotCount to number of rotate sessions used by other displays
1841 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1842 // Count the number of rotator sessions required for current display
1843 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1844 if(!mCurrentFrame.isFBComposed[index]) {
1845 hwc_layer_1_t* layer = &list->hwLayers[index];
1846 private_handle_t *hnd = (private_handle_t *)layer->handle;
1847 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1848 rotCount++;
1849 }
1850 }
1851 }
1852 // if number of layers to rotate exceeds max rotator sessions, bail out.
1853 if(rotCount > RotMgr::MAX_ROT_SESS) {
1854 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1855 __FUNCTION__, mDpy);
1856 return false;
1857 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001858 return true;
1859}
1860
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301861bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1862 hwc_display_contents_1_t* list) {
1863
1864 //A-family hw limitation:
1865 //If a layer need alpha scaling, MDP can not support.
1866 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1867 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1868 if(!mCurrentFrame.isFBComposed[i] &&
1869 isAlphaScaled( &list->hwLayers[i])) {
1870 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1871 return false;
1872 }
1873 }
1874 }
1875
1876 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1877 //If multiple layers requires downscaling and also they are overlapping
1878 //fall back to GPU since MDSS can not handle it.
1879 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1880 qdutils::MDPVersion::getInstance().is8x26()) {
1881 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1882 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1883 if(!mCurrentFrame.isFBComposed[i] &&
1884 isDownscaleRequired(botLayer)) {
1885 //if layer-i is marked for MDP and needs downscaling
1886 //check if any MDP layer on top of i & overlaps with layer-i
1887 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1888 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1889 if(!mCurrentFrame.isFBComposed[j] &&
1890 isDownscaleRequired(topLayer)) {
1891 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1892 topLayer->displayFrame);
1893 if(isValidRect(r))
1894 return false;
1895 }
1896 }
1897 }
1898 }
1899 }
1900 return true;
1901}
1902
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301903void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1904 //For primary display, set the dynamic refreshrate
1905 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1906 ctx->mUseMetaDataRefreshRate) {
1907 FrameInfo frame;
1908 frame.reset(mCurrentFrame.layerCount);
1909 memset(&frame.drop, 0, sizeof(frame.drop));
1910 frame.dropCount = 0;
1911 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1912 __FUNCTION__);
1913 updateLayerCache(ctx, list, frame);
1914 updateYUV(ctx, list, false /*secure only*/, frame);
1915 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1916 MDPVersion& mdpHw = MDPVersion::getInstance();
1917 if(sIdleFallBack) {
1918 //Set minimum panel refresh rate during idle timeout
1919 refreshRate = mdpHw.getMinFpsSupported();
1920 } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1921 (frame.layerCount == 1)) {
1922 //Set the new fresh rate, if there is only one updating YUV layer
1923 //or there is one single RGB layer with this request
1924 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1925 }
1926 setRefreshRate(ctx, mDpy, refreshRate);
1927 }
1928}
1929
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001930int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001931 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001932 char property[PROPERTY_VALUE_MAX];
1933
Raj Kamal4393eaa2014-06-06 13:45:20 +05301934 if(!ctx || !list) {
1935 ALOGE("%s: Invalid context or list",__FUNCTION__);
1936 mCachedFrame.reset();
1937 return -1;
1938 }
1939
1940 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001941 if(mDpy == HWC_DISPLAY_PRIMARY) {
1942 sSimulationFlags = 0;
1943 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1944 int currentFlags = atoi(property);
1945 if(currentFlags != sSimulationFlags) {
1946 sSimulationFlags = currentFlags;
1947 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1948 sSimulationFlags, sSimulationFlags);
1949 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001950 }
1951 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001952 // reset PTOR
1953 if(!mDpy)
1954 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001955
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301956 //reset old data
1957 mCurrentFrame.reset(numLayers);
1958 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1959 mCurrentFrame.dropCount = 0;
1960
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301961 //Do not cache the information for next draw cycle.
1962 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1963 ALOGI("%s: Unsupported layer count for mdp composition",
1964 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001965 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301966#ifdef DYNAMIC_FPS
1967 setDynRefreshRate(ctx, list);
1968#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001969 return -1;
1970 }
1971
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001972 // Detect the start of animation and fall back to GPU only once to cache
1973 // all the layers in FB and display FB content untill animation completes.
1974 if(ctx->listStats[mDpy].isDisplayAnimating) {
1975 mCurrentFrame.needsRedraw = false;
1976 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1977 mCurrentFrame.needsRedraw = true;
1978 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1979 }
1980 setMDPCompLayerFlags(ctx, list);
1981 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301982#ifdef DYNAMIC_FPS
1983 setDynRefreshRate(ctx, list);
1984#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001985 ret = -1;
1986 return ret;
1987 } else {
1988 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1989 }
1990
Saurabh Shahb39f8152013-08-22 10:21:44 -07001991 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001992 if(isFrameDoable(ctx)) {
1993 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001994 // if AIV Video mode is enabled, drop all non AIV layers from the
1995 // external display list.
1996 if(ctx->listStats[mDpy].mAIVVideoMode) {
1997 dropNonAIVLayers(ctx, list);
1998 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001999
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002000 // if tryFullFrame fails, try to push all video and secure RGB layers
2001 // to MDP for composition.
2002 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002003 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302004 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002005 setMDPCompLayerFlags(ctx, list);
2006 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002007 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002008 reset(ctx);
2009 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2010 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002011 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002012 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2013 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002014 }
2015 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302016 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2017 enablePartialUpdateForMDP3) {
2018 generateROI(ctx, list);
2019 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2020 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2021 }
2022 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002023 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2024 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002025 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002026 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002027
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002028 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002029 ALOGD("GEOMETRY change: %d",
2030 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002031 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002032 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002033 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002034 }
2035
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002036#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302037 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002038#endif
2039
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002040 mCachedFrame.cacheAll(list);
2041 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002042 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002043}
2044
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002045bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302046
2047 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302048 int mdpIndex = mCurrentFrame.layerToMDP[index];
2049 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2050 info.pipeInfo = new MdpYUVPipeInfo;
2051 info.rot = NULL;
2052 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302053
2054 pipe_info.lIndex = ovutils::OV_INVALID;
2055 pipe_info.rIndex = ovutils::OV_INVALID;
2056
Saurabh Shahc62f3982014-03-05 14:28:26 -08002057 Overlay::PipeSpecs pipeSpecs;
2058 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2059 pipeSpecs.needsScaling = true;
2060 pipeSpecs.dpy = mDpy;
2061 pipeSpecs.fb = false;
2062
2063 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302064 if(pipe_info.lIndex == ovutils::OV_INVALID){
2065 bRet = false;
2066 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2067 __FUNCTION__);
2068 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002069 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302070 if(pipe_info.rIndex == ovutils::OV_INVALID){
2071 bRet = false;
2072 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2073 __FUNCTION__);
2074 }
2075 return bRet;
2076}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002077
2078int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2079 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002080 if (ctx->mPtorInfo.isActive()) {
2081 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002082 if (fd < 0) {
2083 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002084 }
2085 }
2086 return fd;
2087}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002088//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002089
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002090void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302091 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002092 //If 4k2k Yuv layer split is possible, and if
2093 //fbz is above 4k2k layer, increment fb zorder by 1
2094 //as we split 4k2k layer and increment zorder for right half
2095 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002096 if(!ctx)
2097 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002098 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302099 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2100 index++) {
2101 if(!mCurrentFrame.isFBComposed[index]) {
2102 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2103 mdpNextZOrder++;
2104 }
2105 mdpNextZOrder++;
2106 hwc_layer_1_t* layer = &list->hwLayers[index];
2107 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302108 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302109 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2110 mCurrentFrame.fbZ += 1;
2111 mdpNextZOrder++;
2112 //As we split 4kx2k yuv layer and program to 2 VG pipes
2113 //(if available) increase mdpcount by 1.
2114 mCurrentFrame.mdpCount++;
2115 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002116 }
2117 }
2118 }
radhakrishnac9a67412013-09-25 17:40:42 +05302119}
2120
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002121/*
2122 * Configures pipe(s) for MDP composition
2123 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002124int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002125 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002126 MdpPipeInfoNonSplit& mdp_info =
2127 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302128 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002129 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002130 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002131
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002132 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2133 __FUNCTION__, layer, zOrder, dest);
2134
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002135 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002136 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137}
2138
Saurabh Shah88e4d272013-09-03 13:31:29 -07002139bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002140 hwc_display_contents_1_t* list) {
2141 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002142
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002143 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002144
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002145 hwc_layer_1_t* layer = &list->hwLayers[index];
2146 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302147 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002148 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302149 continue;
2150 }
2151 }
2152
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002153 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002154 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002155 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002156 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002157 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002158
Saurabh Shahc62f3982014-03-05 14:28:26 -08002159 Overlay::PipeSpecs pipeSpecs;
2160 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2161 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2162 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2163 (qdutils::MDPVersion::getInstance().is8x26() and
2164 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2165 pipeSpecs.dpy = mDpy;
2166 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002167 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002168
Saurabh Shahc62f3982014-03-05 14:28:26 -08002169 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2170
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002171 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002172 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002173 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002174 }
2175 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002176 return true;
2177}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002178
radhakrishnac9a67412013-09-25 17:40:42 +05302179int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2180 PipeLayerPair& PipeLayerPair) {
2181 MdpYUVPipeInfo& mdp_info =
2182 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2183 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302184 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302185 eDest lDest = mdp_info.lIndex;
2186 eDest rDest = mdp_info.rIndex;
2187
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002188 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302189 lDest, rDest, &PipeLayerPair.rot);
2190}
2191
Saurabh Shah88e4d272013-09-03 13:31:29 -07002192bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002193
Raj Kamal4393eaa2014-06-06 13:45:20 +05302194 if(!isEnabled() or !mModeOn) {
2195 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302196 return true;
2197 }
2198
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002199 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002200 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002201 sHandleTimeout = true;
2202 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002203
2204 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002205 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002206
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002207 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2208 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002209 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002210 if(mCurrentFrame.isFBComposed[i]) continue;
2211
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002212 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002213 private_handle_t *hnd = (private_handle_t *)layer->handle;
2214 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002215 if (!(layer->flags & HWC_COLOR_FILL)) {
2216 ALOGE("%s handle null", __FUNCTION__);
2217 return false;
2218 }
2219 // No PLAY for Color layer
2220 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2221 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002222 }
2223
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002224 int mdpIndex = mCurrentFrame.layerToMDP[i];
2225
Raj Kamal389d6e32014-08-04 14:43:24 +05302226 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302227 {
2228 MdpYUVPipeInfo& pipe_info =
2229 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2230 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2231 ovutils::eDest indexL = pipe_info.lIndex;
2232 ovutils::eDest indexR = pipe_info.rIndex;
2233 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302234 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302235 if(rot) {
2236 rot->queueBuffer(fd, offset);
2237 fd = rot->getDstMemId();
2238 offset = rot->getDstOffset();
2239 }
2240 if(indexL != ovutils::OV_INVALID) {
2241 ovutils::eDest destL = (ovutils::eDest)indexL;
2242 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2243 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2244 if (!ov.queueBuffer(fd, offset, destL)) {
2245 ALOGE("%s: queueBuffer failed for display:%d",
2246 __FUNCTION__, mDpy);
2247 return false;
2248 }
2249 }
2250
2251 if(indexR != ovutils::OV_INVALID) {
2252 ovutils::eDest destR = (ovutils::eDest)indexR;
2253 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2254 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2255 if (!ov.queueBuffer(fd, offset, destR)) {
2256 ALOGE("%s: queueBuffer failed for display:%d",
2257 __FUNCTION__, mDpy);
2258 return false;
2259 }
2260 }
2261 }
2262 else{
2263 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002264 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302265 ovutils::eDest dest = pipe_info.index;
2266 if(dest == ovutils::OV_INVALID) {
2267 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002268 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302269 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002270
radhakrishnac9a67412013-09-25 17:40:42 +05302271 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2272 continue;
2273 }
2274
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002275 int fd = hnd->fd;
2276 uint32_t offset = (uint32_t)hnd->offset;
2277 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2278 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002279 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002280 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002281 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002282 }
2283
radhakrishnac9a67412013-09-25 17:40:42 +05302284 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2285 using pipe: %d", __FUNCTION__, layer,
2286 hnd, dest );
2287
radhakrishnac9a67412013-09-25 17:40:42 +05302288 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2289 if(rot) {
2290 if(!rot->queueBuffer(fd, offset))
2291 return false;
2292 fd = rot->getDstMemId();
2293 offset = rot->getDstOffset();
2294 }
2295
2296 if (!ov.queueBuffer(fd, offset, dest)) {
2297 ALOGE("%s: queueBuffer failed for display:%d ",
2298 __FUNCTION__, mDpy);
2299 return false;
2300 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002301 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002302
2303 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002304 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002305 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002306}
2307
Saurabh Shah88e4d272013-09-03 13:31:29 -07002308//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002309
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002310void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302311 hwc_display_contents_1_t* list){
2312 //if 4kx2k yuv layer is totally present in either in left half
2313 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302314 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302315 if(mCurrentFrame.fbZ >= 0) {
2316 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2317 index++) {
2318 if(!mCurrentFrame.isFBComposed[index]) {
2319 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2320 mdpNextZOrder++;
2321 }
2322 mdpNextZOrder++;
2323 hwc_layer_1_t* layer = &list->hwLayers[index];
2324 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302325 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302326 hwc_rect_t dst = layer->displayFrame;
2327 if((dst.left > lSplit) || (dst.right < lSplit)) {
2328 mCurrentFrame.mdpCount += 1;
2329 }
2330 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2331 mCurrentFrame.fbZ += 1;
2332 mdpNextZOrder++;
2333 }
2334 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002335 }
radhakrishnac9a67412013-09-25 17:40:42 +05302336 }
2337}
2338
Saurabh Shah88e4d272013-09-03 13:31:29 -07002339bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002340 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002341
Saurabh Shahc62f3982014-03-05 14:28:26 -08002342 const int lSplit = getLeftSplit(ctx, mDpy);
2343 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002344 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002345 pipe_info.lIndex = ovutils::OV_INVALID;
2346 pipe_info.rIndex = ovutils::OV_INVALID;
2347
Saurabh Shahc62f3982014-03-05 14:28:26 -08002348 Overlay::PipeSpecs pipeSpecs;
2349 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2350 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2351 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2352 pipeSpecs.dpy = mDpy;
2353 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2354 pipeSpecs.fb = false;
2355
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002356 // Acquire pipe only for the updating half
2357 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2358 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2359
2360 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002361 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002362 if(pipe_info.lIndex == ovutils::OV_INVALID)
2363 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002364 }
2365
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002366 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002367 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2368 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002369 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002370 return false;
2371 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002372
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002373 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002374}
2375
Saurabh Shah88e4d272013-09-03 13:31:29 -07002376bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002377 hwc_display_contents_1_t* list) {
2378 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002379
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002380 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002381
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002382 hwc_layer_1_t* layer = &list->hwLayers[index];
2383 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302384 hwc_rect_t dst = layer->displayFrame;
2385 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302386 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302387 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002388 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302389 continue;
2390 }
2391 }
2392 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002393 int mdpIndex = mCurrentFrame.layerToMDP[index];
2394 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002395 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002396 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002397 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002398
Saurabh Shahc62f3982014-03-05 14:28:26 -08002399 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2400 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2401 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002402 return false;
2403 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002404 }
2405 return true;
2406}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002407
radhakrishnac9a67412013-09-25 17:40:42 +05302408int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2409 PipeLayerPair& PipeLayerPair) {
2410 const int lSplit = getLeftSplit(ctx, mDpy);
2411 hwc_rect_t dst = layer->displayFrame;
2412 if((dst.left > lSplit)||(dst.right < lSplit)){
2413 MdpYUVPipeInfo& mdp_info =
2414 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2415 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302416 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302417 eDest lDest = mdp_info.lIndex;
2418 eDest rDest = mdp_info.rIndex;
2419
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002420 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302421 lDest, rDest, &PipeLayerPair.rot);
2422 }
2423 else{
2424 return configure(ctx, layer, PipeLayerPair);
2425 }
2426}
2427
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002428/*
2429 * Configures pipe(s) for MDP composition
2430 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002431int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002432 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002433 MdpPipeInfoSplit& mdp_info =
2434 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002435 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302436 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002437 eDest lDest = mdp_info.lIndex;
2438 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002439
2440 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002441 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002442
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002443 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002444 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002445}
2446
Saurabh Shah88e4d272013-09-03 13:31:29 -07002447bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002448
Raj Kamal4393eaa2014-06-06 13:45:20 +05302449 if(!isEnabled() or !mModeOn) {
2450 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302451 return true;
2452 }
2453
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002454 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002455 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002456 sHandleTimeout = true;
2457 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002458
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002459 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002460 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002461
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002462 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2463 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002464 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002465 if(mCurrentFrame.isFBComposed[i]) continue;
2466
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002467 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002468 private_handle_t *hnd = (private_handle_t *)layer->handle;
2469 if(!hnd) {
2470 ALOGE("%s handle null", __FUNCTION__);
2471 return false;
2472 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002473
2474 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2475 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002476 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002477
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002478 int mdpIndex = mCurrentFrame.layerToMDP[i];
2479
Raj Kamal389d6e32014-08-04 14:43:24 +05302480 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302481 {
2482 MdpYUVPipeInfo& pipe_info =
2483 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2484 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2485 ovutils::eDest indexL = pipe_info.lIndex;
2486 ovutils::eDest indexR = pipe_info.rIndex;
2487 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302488 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302489 if(rot) {
2490 rot->queueBuffer(fd, offset);
2491 fd = rot->getDstMemId();
2492 offset = rot->getDstOffset();
2493 }
2494 if(indexL != ovutils::OV_INVALID) {
2495 ovutils::eDest destL = (ovutils::eDest)indexL;
2496 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2497 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2498 if (!ov.queueBuffer(fd, offset, destL)) {
2499 ALOGE("%s: queueBuffer failed for display:%d",
2500 __FUNCTION__, mDpy);
2501 return false;
2502 }
2503 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002504
radhakrishnac9a67412013-09-25 17:40:42 +05302505 if(indexR != ovutils::OV_INVALID) {
2506 ovutils::eDest destR = (ovutils::eDest)indexR;
2507 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2508 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2509 if (!ov.queueBuffer(fd, offset, destR)) {
2510 ALOGE("%s: queueBuffer failed for display:%d",
2511 __FUNCTION__, mDpy);
2512 return false;
2513 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002514 }
2515 }
radhakrishnac9a67412013-09-25 17:40:42 +05302516 else{
2517 MdpPipeInfoSplit& pipe_info =
2518 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2519 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002520
radhakrishnac9a67412013-09-25 17:40:42 +05302521 ovutils::eDest indexL = pipe_info.lIndex;
2522 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002523
radhakrishnac9a67412013-09-25 17:40:42 +05302524 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002525 uint32_t offset = (uint32_t)hnd->offset;
2526 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2527 if (!mDpy && (index != -1)) {
2528 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2529 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002530 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002531 }
radhakrishnac9a67412013-09-25 17:40:42 +05302532
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002533 if(ctx->mAD->draw(ctx, fd, offset)) {
2534 fd = ctx->mAD->getDstFd();
2535 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002536 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002537
radhakrishnac9a67412013-09-25 17:40:42 +05302538 if(rot) {
2539 rot->queueBuffer(fd, offset);
2540 fd = rot->getDstMemId();
2541 offset = rot->getDstOffset();
2542 }
2543
2544 //************* play left mixer **********
2545 if(indexL != ovutils::OV_INVALID) {
2546 ovutils::eDest destL = (ovutils::eDest)indexL;
2547 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2548 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2549 if (!ov.queueBuffer(fd, offset, destL)) {
2550 ALOGE("%s: queueBuffer failed for left mixer",
2551 __FUNCTION__);
2552 return false;
2553 }
2554 }
2555
2556 //************* play right mixer **********
2557 if(indexR != ovutils::OV_INVALID) {
2558 ovutils::eDest destR = (ovutils::eDest)indexR;
2559 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2560 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2561 if (!ov.queueBuffer(fd, offset, destR)) {
2562 ALOGE("%s: queueBuffer failed for right mixer",
2563 __FUNCTION__);
2564 return false;
2565 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002566 }
2567 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002568
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002569 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2570 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002571
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002572 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002573}
Saurabh Shahab47c692014-02-12 18:45:57 -08002574
2575//================MDPCompSrcSplit==============================================
2576bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002577 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002578 private_handle_t *hnd = (private_handle_t *)layer->handle;
2579 hwc_rect_t dst = layer->displayFrame;
2580 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2581 pipe_info.lIndex = ovutils::OV_INVALID;
2582 pipe_info.rIndex = ovutils::OV_INVALID;
2583
2584 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2585 //should have a higher priority than the right one. Pipe priorities are
2586 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002587
Saurabh Shahc62f3982014-03-05 14:28:26 -08002588 Overlay::PipeSpecs pipeSpecs;
2589 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2590 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2591 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2592 pipeSpecs.dpy = mDpy;
2593 pipeSpecs.fb = false;
2594
Saurabh Shahab47c692014-02-12 18:45:57 -08002595 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002596 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002597 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002598 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002599 }
2600
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002601 /* Use 2 pipes IF
2602 a) Layer's crop width is > 2048 or
2603 b) Layer's dest width > 2048 or
2604 c) On primary, driver has indicated with caps to split always. This is
2605 based on an empirically derived value of panel height. Applied only
2606 if the layer's width is > mixer's width
2607 */
2608
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302609 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002610 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302611 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002612 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2613 const uint32_t dstWidth = dst.right - dst.left;
2614 const uint32_t dstHeight = dst.bottom - dst.top;
2615 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002616 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002617 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2618 crop.bottom - crop.top;
2619 //Approximation to actual clock, ignoring the common factors in pipe and
2620 //mixer cases like line_time
2621 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2622 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002623
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002624 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2625 //pipe line length, we are still using 2 pipes. This is fine just because
2626 //this is source split where destination doesn't matter. Evaluate later to
2627 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002628 if(dstWidth > mdpHw.getMaxPipeWidth() or
2629 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002630 (primarySplitAlways and
2631 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002632 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002633 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002634 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002635 }
2636
2637 // Return values
2638 // 1 Left pipe is higher priority, do nothing.
2639 // 0 Pipes of same priority.
2640 //-1 Right pipe is of higher priority, needs swap.
2641 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2642 pipe_info.rIndex) == -1) {
2643 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002644 }
2645 }
2646
2647 return true;
2648}
2649
Saurabh Shahab47c692014-02-12 18:45:57 -08002650int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2651 PipeLayerPair& PipeLayerPair) {
2652 private_handle_t *hnd = (private_handle_t *)layer->handle;
2653 if(!hnd) {
2654 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2655 return -1;
2656 }
2657 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2658 MdpPipeInfoSplit& mdp_info =
2659 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2660 Rotator **rot = &PipeLayerPair.rot;
2661 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002662 eDest lDest = mdp_info.lIndex;
2663 eDest rDest = mdp_info.rIndex;
2664 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2665 hwc_rect_t dst = layer->displayFrame;
2666 int transform = layer->transform;
2667 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668 int rotFlags = ROT_FLAGS_NONE;
2669 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2670 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2671
2672 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2673 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2674
2675 // Handle R/B swap
2676 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2677 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2678 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2679 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2680 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2681 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002682 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002683 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2684 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002685 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002686 /* Calculate the external display position based on MDP downscale,
2687 ActionSafe, and extorientation features. */
2688 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002689
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002690 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302691 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002692 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002693
2694 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2695 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002696 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002697 }
2698
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002699 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002700 (*rot) = ctx->mRotMgr->getNext();
2701 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002702 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002703 //If the video is using a single pipe, enable BWC
2704 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002705 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2706 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002707 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002708 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002709 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002710 ALOGE("%s: configRotator failed!", __FUNCTION__);
2711 return -1;
2712 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002713 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002714 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002715 }
2716
2717 //If 2 pipes being used, divide layer into half, crop and dst
2718 hwc_rect_t cropL = crop;
2719 hwc_rect_t cropR = crop;
2720 hwc_rect_t dstL = dst;
2721 hwc_rect_t dstR = dst;
2722 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2723 cropL.right = (crop.right + crop.left) / 2;
2724 cropR.left = cropL.right;
2725 sanitizeSourceCrop(cropL, cropR, hnd);
2726
Saurabh Shahb729b192014-08-15 18:04:24 -07002727 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002728 //Swap crops on H flip since 2 pipes are being used
2729 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2730 hwc_rect_t tmp = cropL;
2731 cropL = cropR;
2732 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002733 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002734 }
2735
Saurabh Shahb729b192014-08-15 18:04:24 -07002736 //cropSwap trick: If the src and dst widths are both odd, let us say
2737 //2507, then splitting both into half would cause left width to be 1253
2738 //and right 1254. If crop is swapped because of H flip, this will cause
2739 //left crop width to be 1254, whereas left dst width remains 1253, thus
2740 //inducing a scaling that is unaccounted for. To overcome that we add 1
2741 //to the dst width if there is a cropSwap. So if the original width was
2742 //2507, the left dst width will be 1254. Even if the original width was
2743 //even for ex: 2508, the left dst width will still remain 1254.
2744 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002745 dstR.left = dstL.right;
2746 }
2747
2748 //For the mdp, since either we are pre-rotating or MDP does flips
2749 orient = OVERLAY_TRANSFORM_0;
2750 transform = 0;
2751
2752 //configure left pipe
2753 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002754 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002755 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2756 (ovutils::eBlending) getBlending(layer->blending));
2757
2758 if(configMdp(ctx->mOverlay, pargL, orient,
2759 cropL, dstL, metadata, lDest) < 0) {
2760 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2761 return -1;
2762 }
2763 }
2764
2765 //configure right pipe
2766 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002767 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002768 static_cast<eRotFlags>(rotFlags),
2769 layer->planeAlpha,
2770 (ovutils::eBlending) getBlending(layer->blending));
2771 if(configMdp(ctx->mOverlay, pargR, orient,
2772 cropR, dstR, metadata, rDest) < 0) {
2773 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2774 return -1;
2775 }
2776 }
2777
2778 return 0;
2779}
2780
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002781bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2782 Locker::Autolock _l(ctx->mDrawLock);
2783 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2784 char path[MAX_SYSFS_FILE_PATH];
2785 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2786 int fd = open(path, O_RDONLY);
2787 if(fd < 0) {
2788 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2789 return -1;
2790 }
2791 char value[4];
2792 ssize_t size_read = read(fd, value, sizeof(value)-1);
2793 if(size_read <= 0) {
2794 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2795 close(fd);
2796 return -1;
2797 }
2798 close(fd);
2799 value[size_read] = '\0';
2800 return atoi(value);
2801}
2802
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002803int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2804 Locker::Autolock _l(ctx->mDrawLock);
2805 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2806 char path[MAX_SYSFS_FILE_PATH];
2807 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2808 int fd = open(path, O_WRONLY);
2809 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002810 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002811 return -1;
2812 }
2813 char value[4];
2814 snprintf(value, sizeof(value), "%d", (int)enable);
2815 ssize_t ret = write(fd, value, strlen(value));
2816 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002817 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002818 close(fd);
2819 return -1;
2820 }
2821 close(fd);
2822 sIsPartialUpdateActive = enable;
2823 return 0;
2824}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002825}; //namespace
2826