blob: a5bf0b546be30fd5f1fb926c0dc19e2849e28e62 [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");
1328 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001329 return false;
1330 }
1331
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001332 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1333 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001334 return true;
1335}
1336
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001337/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1338bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1339 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001340 // Fall back to video only composition, if AIV video mode is enabled
1341 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001342 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1343 __FUNCTION__, mDpy);
1344 return false;
1345 }
1346
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001347 const bool secureOnly = true;
1348 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1349 mdpOnlyLayersComp(ctx, list, secureOnly);
1350
1351}
1352
1353bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1354 hwc_display_contents_1_t* list, bool secureOnly) {
1355
1356 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1357 return false;
1358
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301359 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1360 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1361 /* Bail out if we are processing only secured video/ui layers
1362 * and we dont have any */
1363 if(secureOnly) {
1364 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1365 return false;
1366 }
1367 /* No Idle fall back for secure video/ui layers and if there is only
1368 * single layer being composed. */
1369 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1370 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1371 return false;
1372 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001373 }
1374
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001375 mCurrentFrame.reset(numAppLayers);
1376 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1377
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001378 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001379 /* mark secure RGB layers for MDP comp */
1380 updateSecureRGB(ctx, list);
1381
1382 if(mCurrentFrame.mdpCount == 0) {
1383 reset(ctx);
1384 return false;
1385 }
1386
1387 /* find the maximum batch of layers to be marked for framebuffer */
1388 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1389 if(!ret) {
1390 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1391 reset(ctx);
1392 return false;
1393 }
1394
1395 if(sEnableYUVsplit){
1396 adjustForSourceSplit(ctx, list);
1397 }
1398
1399 if(!postHeuristicsHandling(ctx, list)) {
1400 ALOGD_IF(isDebug(), "post heuristic handling failed");
1401 reset(ctx);
1402 return false;
1403 }
1404
1405 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1406 __FUNCTION__);
1407 return true;
1408}
1409
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001410/* Checks for conditions where YUV layers cannot be bypassed */
1411bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001412 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001413 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001414 return false;
1415 }
1416
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001417 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001418 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1419 return false;
1420 }
1421
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001422 if(isSecuring(ctx, layer)) {
1423 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1424 return false;
1425 }
1426
Saurabh Shah4fdde762013-04-30 18:47:33 -07001427 if(!isValidDimension(ctx, layer)) {
1428 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1429 __FUNCTION__);
1430 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001431 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001432
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001433 if(layer->planeAlpha < 0xFF) {
1434 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1435 in video only mode",
1436 __FUNCTION__);
1437 return false;
1438 }
1439
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001440 return true;
1441}
1442
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001443/* Checks for conditions where Secure RGB layers cannot be bypassed */
1444bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1445 if(isSkipLayer(layer)) {
1446 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1447 __FUNCTION__, mDpy);
1448 return false;
1449 }
1450
1451 if(isSecuring(ctx, layer)) {
1452 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1453 return false;
1454 }
1455
1456 if(not isSupportedForMDPComp(ctx, layer)) {
1457 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1458 __FUNCTION__);
1459 return false;
1460 }
1461 return true;
1462}
1463
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301464/* starts at fromIndex and check for each layer to find
1465 * if it it has overlapping with any Updating layer above it in zorder
1466 * till the end of the batch. returns true if it finds any intersection */
1467bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1468 int fromIndex, int toIndex) {
1469 for(int i = fromIndex; i < toIndex; i++) {
1470 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1471 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1472 return false;
1473 }
1474 }
1475 }
1476 return true;
1477}
1478
1479/* Checks if given layer at targetLayerIndex has any
1480 * intersection with all the updating layers in beween
1481 * fromIndex and toIndex. Returns true if it finds intersectiion */
1482bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1483 int fromIndex, int toIndex, int targetLayerIndex) {
1484 for(int i = fromIndex; i <= toIndex; i++) {
1485 if(!mCurrentFrame.isFBComposed[i]) {
1486 if(areLayersIntersecting(&list->hwLayers[i],
1487 &list->hwLayers[targetLayerIndex])) {
1488 return true;
1489 }
1490 }
1491 }
1492 return false;
1493}
1494
1495int MDPComp::getBatch(hwc_display_contents_1_t* list,
1496 int& maxBatchStart, int& maxBatchEnd,
1497 int& maxBatchCount) {
1498 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301499 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001500 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301501 while (i < mCurrentFrame.layerCount) {
1502 int batchCount = 0;
1503 int batchStart = i;
1504 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001505 /* Adjust batch Z order with the dropped layers so far */
1506 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301507 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301508 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301509 while(i < mCurrentFrame.layerCount) {
1510 if(!mCurrentFrame.isFBComposed[i]) {
1511 if(!batchCount) {
1512 i++;
1513 break;
1514 }
1515 updatingLayersAbove++;
1516 i++;
1517 continue;
1518 } else {
1519 if(mCurrentFrame.drop[i]) {
1520 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001521 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301522 continue;
1523 } else if(updatingLayersAbove <= 0) {
1524 batchCount++;
1525 batchEnd = i;
1526 i++;
1527 continue;
1528 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1529
1530 // We have a valid updating layer already. If layer-i not
1531 // have overlapping with all updating layers in between
1532 // batch-start and i, then we can add layer i to batch.
1533 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1534 batchCount++;
1535 batchEnd = i;
1536 i++;
1537 continue;
1538 } else if(canPushBatchToTop(list, batchStart, i)) {
1539 //If All the non-updating layers with in this batch
1540 //does not have intersection with the updating layers
1541 //above in z-order, then we can safely move the batch to
1542 //higher z-order. Increment fbZ as it is moving up.
1543 if( firstZReverseIndex < 0) {
1544 firstZReverseIndex = i;
1545 }
1546 batchCount++;
1547 batchEnd = i;
1548 fbZ += updatingLayersAbove;
1549 i++;
1550 updatingLayersAbove = 0;
1551 continue;
1552 } else {
1553 //both failed.start the loop again from here.
1554 if(firstZReverseIndex >= 0) {
1555 i = firstZReverseIndex;
1556 }
1557 break;
1558 }
1559 }
1560 }
1561 }
1562 if(batchCount > maxBatchCount) {
1563 maxBatchCount = batchCount;
1564 maxBatchStart = batchStart;
1565 maxBatchEnd = batchEnd;
1566 fbZOrder = fbZ;
1567 }
1568 }
1569 return fbZOrder;
1570}
1571
1572bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1573 hwc_display_contents_1_t* list) {
1574 /* Idea is to keep as many non-updating(cached) layers in FB and
1575 * send rest of them through MDP. This is done in 2 steps.
1576 * 1. Find the maximum contiguous batch of non-updating layers.
1577 * 2. See if we can improve this batch size for caching by adding
1578 * opaque layers around the batch, if they don't have
1579 * any overlapping with the updating layers in between.
1580 * NEVER mark an updating layer for caching.
1581 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001582
1583 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001584 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001585 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301586 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001587
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001588 /* Nothing is cached. No batching needed */
1589 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001590 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001591 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001592
1593 /* No MDP comp layers, try to use other comp modes */
1594 if(mCurrentFrame.mdpCount == 0) {
1595 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001596 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001597
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301598 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001599
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301600 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001601 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001602 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001603 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301604 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001605 if(!mCurrentFrame.drop[i]){
1606 //If an unsupported layer is being attempted to
1607 //be pulled out we should fail
1608 if(not isSupportedForMDPComp(ctx, layer)) {
1609 return false;
1610 }
1611 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001612 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001613 }
1614 }
1615
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301616 // update the frame data
1617 mCurrentFrame.fbZ = fbZ;
1618 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001619 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001620 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621
1622 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301623 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001624
1625 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001627
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001628void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001629 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001630 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001631 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001632
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001633 for(int i = 0; i < numAppLayers; i++) {
1634 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001635 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001636 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001637 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001638 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001639 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001640 }
1641 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001642
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001643 frame.fbCount = fbCount;
1644 frame.mdpCount = frame.layerCount - frame.fbCount
1645 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001646
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001647 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1648 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001649}
1650
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001651// drop other non-AIV layers from external display list.
1652void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001653 hwc_display_contents_1_t* list) {
1654 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1655 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001656 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001657 mCurrentFrame.dropCount++;
1658 mCurrentFrame.drop[i] = true;
1659 }
1660 }
1661 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1662 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1663 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1664 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1665 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1666 mCurrentFrame.dropCount);
1667}
1668
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001669void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001670 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001671 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1672 for(int index = 0;index < nYuvCount; index++){
1673 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1674 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1675
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001676 if(mCurrentFrame.drop[nYuvIndex]) {
1677 continue;
1678 }
1679
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001680 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001681 if(!frame.isFBComposed[nYuvIndex]) {
1682 frame.isFBComposed[nYuvIndex] = true;
1683 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001684 }
1685 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001686 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001687 private_handle_t *hnd = (private_handle_t *)layer->handle;
1688 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001689 frame.isFBComposed[nYuvIndex] = false;
1690 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001691 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001692 }
1693 }
1694 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001695
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001696 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1697 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001698}
1699
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001700void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1701 hwc_display_contents_1_t* list) {
1702 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1703 for(int index = 0;index < nSecureRGBCount; index++){
1704 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1705 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1706
1707 if(!isSecureRGBDoable(ctx, layer)) {
1708 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1709 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1710 mCurrentFrame.fbCount++;
1711 }
1712 } else {
1713 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1714 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1715 mCurrentFrame.fbCount--;
1716 }
1717 }
1718 }
1719
1720 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1721 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1722 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1723 mCurrentFrame.fbCount);
1724}
1725
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001726hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1727 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001728 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001729
1730 /* Update only the region of FB needed for composition */
1731 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1732 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1733 hwc_layer_1_t* layer = &list->hwLayers[i];
1734 hwc_rect_t dst = layer->displayFrame;
1735 fbRect = getUnion(fbRect, dst);
1736 }
1737 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001738 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001739 return fbRect;
1740}
1741
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001742bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1743 hwc_display_contents_1_t* list) {
1744
1745 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001746 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001747 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1748 return false;
1749 }
1750
1751 //Limitations checks
1752 if(!hwLimitationsCheck(ctx, list)) {
1753 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1754 return false;
1755 }
1756
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001757 //Configure framebuffer first if applicable
1758 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001759 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001760 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1761 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001762 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1763 __FUNCTION__);
1764 return false;
1765 }
1766 }
1767
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001768 mCurrentFrame.map();
1769
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001770 if(!allocLayerPipes(ctx, list)) {
1771 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001772 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001773 }
1774
1775 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001776 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001777 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001778 int mdpIndex = mCurrentFrame.layerToMDP[index];
1779 hwc_layer_1_t* layer = &list->hwLayers[index];
1780
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301781 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1782 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1783 mdpNextZOrder++;
1784 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001785 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1786 cur_pipe->zOrder = mdpNextZOrder++;
1787
radhakrishnac9a67412013-09-25 17:40:42 +05301788 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301789 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301790 if(configure4k2kYuv(ctx, layer,
1791 mCurrentFrame.mdpToLayer[mdpIndex])
1792 != 0 ){
1793 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1794 for layer %d",__FUNCTION__, index);
1795 return false;
1796 }
1797 else{
1798 mdpNextZOrder++;
1799 }
1800 continue;
1801 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001802 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1803 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301804 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001805 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001806 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001807 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001808 }
1809
Saurabh Shaha36be922013-12-16 18:18:39 -08001810 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1811 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1812 ,__FUNCTION__, mDpy);
1813 return false;
1814 }
1815
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001816 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001817 return true;
1818}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001819
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001820bool MDPComp::resourceCheck(hwc_context_t* ctx,
1821 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001822 const bool fbUsed = mCurrentFrame.fbCount;
1823 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1824 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1825 return false;
1826 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001827
1828 //Will benefit cases where a video has non-updating background.
1829 if((mDpy > HWC_DISPLAY_PRIMARY) and
1830 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1831 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1832 return false;
1833 }
1834
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001835 // Init rotCount to number of rotate sessions used by other displays
1836 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1837 // Count the number of rotator sessions required for current display
1838 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1839 if(!mCurrentFrame.isFBComposed[index]) {
1840 hwc_layer_1_t* layer = &list->hwLayers[index];
1841 private_handle_t *hnd = (private_handle_t *)layer->handle;
1842 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1843 rotCount++;
1844 }
1845 }
1846 }
1847 // if number of layers to rotate exceeds max rotator sessions, bail out.
1848 if(rotCount > RotMgr::MAX_ROT_SESS) {
1849 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1850 __FUNCTION__, mDpy);
1851 return false;
1852 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001853 return true;
1854}
1855
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301856bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1857 hwc_display_contents_1_t* list) {
1858
1859 //A-family hw limitation:
1860 //If a layer need alpha scaling, MDP can not support.
1861 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1862 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1863 if(!mCurrentFrame.isFBComposed[i] &&
1864 isAlphaScaled( &list->hwLayers[i])) {
1865 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1866 return false;
1867 }
1868 }
1869 }
1870
1871 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1872 //If multiple layers requires downscaling and also they are overlapping
1873 //fall back to GPU since MDSS can not handle it.
1874 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1875 qdutils::MDPVersion::getInstance().is8x26()) {
1876 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1877 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1878 if(!mCurrentFrame.isFBComposed[i] &&
1879 isDownscaleRequired(botLayer)) {
1880 //if layer-i is marked for MDP and needs downscaling
1881 //check if any MDP layer on top of i & overlaps with layer-i
1882 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1883 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1884 if(!mCurrentFrame.isFBComposed[j] &&
1885 isDownscaleRequired(topLayer)) {
1886 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1887 topLayer->displayFrame);
1888 if(isValidRect(r))
1889 return false;
1890 }
1891 }
1892 }
1893 }
1894 }
1895 return true;
1896}
1897
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301898void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1899 //For primary display, set the dynamic refreshrate
1900 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1901 ctx->mUseMetaDataRefreshRate) {
1902 FrameInfo frame;
1903 frame.reset(mCurrentFrame.layerCount);
1904 memset(&frame.drop, 0, sizeof(frame.drop));
1905 frame.dropCount = 0;
1906 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1907 __FUNCTION__);
1908 updateLayerCache(ctx, list, frame);
1909 updateYUV(ctx, list, false /*secure only*/, frame);
1910 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1911 MDPVersion& mdpHw = MDPVersion::getInstance();
1912 if(sIdleFallBack) {
1913 //Set minimum panel refresh rate during idle timeout
1914 refreshRate = mdpHw.getMinFpsSupported();
1915 } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1916 (frame.layerCount == 1)) {
1917 //Set the new fresh rate, if there is only one updating YUV layer
1918 //or there is one single RGB layer with this request
1919 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1920 }
1921 setRefreshRate(ctx, mDpy, refreshRate);
1922 }
1923}
1924
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001925int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001926 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001927 char property[PROPERTY_VALUE_MAX];
1928
Raj Kamal4393eaa2014-06-06 13:45:20 +05301929 if(!ctx || !list) {
1930 ALOGE("%s: Invalid context or list",__FUNCTION__);
1931 mCachedFrame.reset();
1932 return -1;
1933 }
1934
1935 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001936 if(mDpy == HWC_DISPLAY_PRIMARY) {
1937 sSimulationFlags = 0;
1938 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1939 int currentFlags = atoi(property);
1940 if(currentFlags != sSimulationFlags) {
1941 sSimulationFlags = currentFlags;
1942 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1943 sSimulationFlags, sSimulationFlags);
1944 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001945 }
1946 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001947 // reset PTOR
1948 if(!mDpy)
1949 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001950
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301951 //reset old data
1952 mCurrentFrame.reset(numLayers);
1953 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1954 mCurrentFrame.dropCount = 0;
1955
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301956 //Do not cache the information for next draw cycle.
1957 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1958 ALOGI("%s: Unsupported layer count for mdp composition",
1959 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001960 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301961#ifdef DYNAMIC_FPS
1962 setDynRefreshRate(ctx, list);
1963#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001964 return -1;
1965 }
1966
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001967 // Detect the start of animation and fall back to GPU only once to cache
1968 // all the layers in FB and display FB content untill animation completes.
1969 if(ctx->listStats[mDpy].isDisplayAnimating) {
1970 mCurrentFrame.needsRedraw = false;
1971 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1972 mCurrentFrame.needsRedraw = true;
1973 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1974 }
1975 setMDPCompLayerFlags(ctx, list);
1976 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301977#ifdef DYNAMIC_FPS
1978 setDynRefreshRate(ctx, list);
1979#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001980 ret = -1;
1981 return ret;
1982 } else {
1983 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1984 }
1985
Saurabh Shahb39f8152013-08-22 10:21:44 -07001986 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001987 if(isFrameDoable(ctx)) {
1988 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001989 // if AIV Video mode is enabled, drop all non AIV layers from the
1990 // external display list.
1991 if(ctx->listStats[mDpy].mAIVVideoMode) {
1992 dropNonAIVLayers(ctx, list);
1993 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001994
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001995 // if tryFullFrame fails, try to push all video and secure RGB layers
1996 // to MDP for composition.
1997 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001998 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301999 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002000 setMDPCompLayerFlags(ctx, list);
2001 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002002 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002003 reset(ctx);
2004 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2005 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002006 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002007 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2008 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002009 }
2010 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302011 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2012 enablePartialUpdateForMDP3) {
2013 generateROI(ctx, list);
2014 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2015 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2016 }
2017 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002018 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2019 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002020 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002021 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002022
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002023 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002024 ALOGD("GEOMETRY change: %d",
2025 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002026 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002027 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002028 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002029 }
2030
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002031#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302032 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002033#endif
2034
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002035 mCachedFrame.cacheAll(list);
2036 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002037 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002038}
2039
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002040bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302041
2042 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302043 int mdpIndex = mCurrentFrame.layerToMDP[index];
2044 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2045 info.pipeInfo = new MdpYUVPipeInfo;
2046 info.rot = NULL;
2047 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302048
2049 pipe_info.lIndex = ovutils::OV_INVALID;
2050 pipe_info.rIndex = ovutils::OV_INVALID;
2051
Saurabh Shahc62f3982014-03-05 14:28:26 -08002052 Overlay::PipeSpecs pipeSpecs;
2053 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2054 pipeSpecs.needsScaling = true;
2055 pipeSpecs.dpy = mDpy;
2056 pipeSpecs.fb = false;
2057
2058 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302059 if(pipe_info.lIndex == ovutils::OV_INVALID){
2060 bRet = false;
2061 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2062 __FUNCTION__);
2063 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002064 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302065 if(pipe_info.rIndex == ovutils::OV_INVALID){
2066 bRet = false;
2067 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2068 __FUNCTION__);
2069 }
2070 return bRet;
2071}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002072
2073int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2074 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002075 if (ctx->mPtorInfo.isActive()) {
2076 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002077 if (fd < 0) {
2078 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002079 }
2080 }
2081 return fd;
2082}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002083//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002084
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002085void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302086 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002087 //If 4k2k Yuv layer split is possible, and if
2088 //fbz is above 4k2k layer, increment fb zorder by 1
2089 //as we split 4k2k layer and increment zorder for right half
2090 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002091 if(!ctx)
2092 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002093 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302094 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2095 index++) {
2096 if(!mCurrentFrame.isFBComposed[index]) {
2097 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2098 mdpNextZOrder++;
2099 }
2100 mdpNextZOrder++;
2101 hwc_layer_1_t* layer = &list->hwLayers[index];
2102 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302103 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302104 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2105 mCurrentFrame.fbZ += 1;
2106 mdpNextZOrder++;
2107 //As we split 4kx2k yuv layer and program to 2 VG pipes
2108 //(if available) increase mdpcount by 1.
2109 mCurrentFrame.mdpCount++;
2110 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002111 }
2112 }
2113 }
radhakrishnac9a67412013-09-25 17:40:42 +05302114}
2115
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002116/*
2117 * Configures pipe(s) for MDP composition
2118 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002119int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002120 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002121 MdpPipeInfoNonSplit& mdp_info =
2122 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302123 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002124 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002125 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002126
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002127 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2128 __FUNCTION__, layer, zOrder, dest);
2129
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002130 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002131 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002132}
2133
Saurabh Shah88e4d272013-09-03 13:31:29 -07002134bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002135 hwc_display_contents_1_t* list) {
2136 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002138 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002139
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002140 hwc_layer_1_t* layer = &list->hwLayers[index];
2141 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302142 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002143 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302144 continue;
2145 }
2146 }
2147
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002148 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002149 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002150 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002151 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002152 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002153
Saurabh Shahc62f3982014-03-05 14:28:26 -08002154 Overlay::PipeSpecs pipeSpecs;
2155 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2156 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2157 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2158 (qdutils::MDPVersion::getInstance().is8x26() and
2159 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2160 pipeSpecs.dpy = mDpy;
2161 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002162 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002163
Saurabh Shahc62f3982014-03-05 14:28:26 -08002164 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2165
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002166 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002167 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002168 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002169 }
2170 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002171 return true;
2172}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002173
radhakrishnac9a67412013-09-25 17:40:42 +05302174int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2175 PipeLayerPair& PipeLayerPair) {
2176 MdpYUVPipeInfo& mdp_info =
2177 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2178 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302179 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302180 eDest lDest = mdp_info.lIndex;
2181 eDest rDest = mdp_info.rIndex;
2182
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002183 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302184 lDest, rDest, &PipeLayerPair.rot);
2185}
2186
Saurabh Shah88e4d272013-09-03 13:31:29 -07002187bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002188
Raj Kamal4393eaa2014-06-06 13:45:20 +05302189 if(!isEnabled() or !mModeOn) {
2190 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302191 return true;
2192 }
2193
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002194 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002195 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002196 sHandleTimeout = true;
2197 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002198
2199 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002200 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002201
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002202 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2203 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002204 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002205 if(mCurrentFrame.isFBComposed[i]) continue;
2206
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002207 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002208 private_handle_t *hnd = (private_handle_t *)layer->handle;
2209 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002210 if (!(layer->flags & HWC_COLOR_FILL)) {
2211 ALOGE("%s handle null", __FUNCTION__);
2212 return false;
2213 }
2214 // No PLAY for Color layer
2215 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2216 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002217 }
2218
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002219 int mdpIndex = mCurrentFrame.layerToMDP[i];
2220
Raj Kamal389d6e32014-08-04 14:43:24 +05302221 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302222 {
2223 MdpYUVPipeInfo& pipe_info =
2224 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2225 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2226 ovutils::eDest indexL = pipe_info.lIndex;
2227 ovutils::eDest indexR = pipe_info.rIndex;
2228 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302229 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302230 if(rot) {
2231 rot->queueBuffer(fd, offset);
2232 fd = rot->getDstMemId();
2233 offset = rot->getDstOffset();
2234 }
2235 if(indexL != ovutils::OV_INVALID) {
2236 ovutils::eDest destL = (ovutils::eDest)indexL;
2237 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2238 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2239 if (!ov.queueBuffer(fd, offset, destL)) {
2240 ALOGE("%s: queueBuffer failed for display:%d",
2241 __FUNCTION__, mDpy);
2242 return false;
2243 }
2244 }
2245
2246 if(indexR != ovutils::OV_INVALID) {
2247 ovutils::eDest destR = (ovutils::eDest)indexR;
2248 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2249 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2250 if (!ov.queueBuffer(fd, offset, destR)) {
2251 ALOGE("%s: queueBuffer failed for display:%d",
2252 __FUNCTION__, mDpy);
2253 return false;
2254 }
2255 }
2256 }
2257 else{
2258 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002259 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302260 ovutils::eDest dest = pipe_info.index;
2261 if(dest == ovutils::OV_INVALID) {
2262 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002263 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302264 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002265
radhakrishnac9a67412013-09-25 17:40:42 +05302266 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2267 continue;
2268 }
2269
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002270 int fd = hnd->fd;
2271 uint32_t offset = (uint32_t)hnd->offset;
2272 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2273 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002274 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002275 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002276 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002277 }
2278
radhakrishnac9a67412013-09-25 17:40:42 +05302279 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2280 using pipe: %d", __FUNCTION__, layer,
2281 hnd, dest );
2282
radhakrishnac9a67412013-09-25 17:40:42 +05302283 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2284 if(rot) {
2285 if(!rot->queueBuffer(fd, offset))
2286 return false;
2287 fd = rot->getDstMemId();
2288 offset = rot->getDstOffset();
2289 }
2290
2291 if (!ov.queueBuffer(fd, offset, dest)) {
2292 ALOGE("%s: queueBuffer failed for display:%d ",
2293 __FUNCTION__, mDpy);
2294 return false;
2295 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002296 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002297
2298 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002299 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002300 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002301}
2302
Saurabh Shah88e4d272013-09-03 13:31:29 -07002303//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002304
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002305void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302306 hwc_display_contents_1_t* list){
2307 //if 4kx2k yuv layer is totally present in either in left half
2308 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302309 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302310 if(mCurrentFrame.fbZ >= 0) {
2311 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2312 index++) {
2313 if(!mCurrentFrame.isFBComposed[index]) {
2314 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2315 mdpNextZOrder++;
2316 }
2317 mdpNextZOrder++;
2318 hwc_layer_1_t* layer = &list->hwLayers[index];
2319 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302320 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302321 hwc_rect_t dst = layer->displayFrame;
2322 if((dst.left > lSplit) || (dst.right < lSplit)) {
2323 mCurrentFrame.mdpCount += 1;
2324 }
2325 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2326 mCurrentFrame.fbZ += 1;
2327 mdpNextZOrder++;
2328 }
2329 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002330 }
radhakrishnac9a67412013-09-25 17:40:42 +05302331 }
2332}
2333
Saurabh Shah88e4d272013-09-03 13:31:29 -07002334bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002335 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002336
Saurabh Shahc62f3982014-03-05 14:28:26 -08002337 const int lSplit = getLeftSplit(ctx, mDpy);
2338 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002339 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002340 pipe_info.lIndex = ovutils::OV_INVALID;
2341 pipe_info.rIndex = ovutils::OV_INVALID;
2342
Saurabh Shahc62f3982014-03-05 14:28:26 -08002343 Overlay::PipeSpecs pipeSpecs;
2344 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2345 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2346 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2347 pipeSpecs.dpy = mDpy;
2348 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2349 pipeSpecs.fb = false;
2350
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002351 // Acquire pipe only for the updating half
2352 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2353 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2354
2355 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002356 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002357 if(pipe_info.lIndex == ovutils::OV_INVALID)
2358 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002359 }
2360
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002361 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002362 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2363 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002364 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002365 return false;
2366 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002367
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002368 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002369}
2370
Saurabh Shah88e4d272013-09-03 13:31:29 -07002371bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002372 hwc_display_contents_1_t* list) {
2373 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002374
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002375 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002376
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002377 hwc_layer_1_t* layer = &list->hwLayers[index];
2378 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302379 hwc_rect_t dst = layer->displayFrame;
2380 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302381 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302382 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002383 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302384 continue;
2385 }
2386 }
2387 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002388 int mdpIndex = mCurrentFrame.layerToMDP[index];
2389 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002390 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002391 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002392 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002393
Saurabh Shahc62f3982014-03-05 14:28:26 -08002394 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2395 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2396 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002397 return false;
2398 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002399 }
2400 return true;
2401}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002402
radhakrishnac9a67412013-09-25 17:40:42 +05302403int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2404 PipeLayerPair& PipeLayerPair) {
2405 const int lSplit = getLeftSplit(ctx, mDpy);
2406 hwc_rect_t dst = layer->displayFrame;
2407 if((dst.left > lSplit)||(dst.right < lSplit)){
2408 MdpYUVPipeInfo& mdp_info =
2409 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2410 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302411 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302412 eDest lDest = mdp_info.lIndex;
2413 eDest rDest = mdp_info.rIndex;
2414
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002415 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302416 lDest, rDest, &PipeLayerPair.rot);
2417 }
2418 else{
2419 return configure(ctx, layer, PipeLayerPair);
2420 }
2421}
2422
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002423/*
2424 * Configures pipe(s) for MDP composition
2425 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002426int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002427 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002428 MdpPipeInfoSplit& mdp_info =
2429 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002430 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302431 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002432 eDest lDest = mdp_info.lIndex;
2433 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002434
2435 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002436 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002437
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002438 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002439 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002440}
2441
Saurabh Shah88e4d272013-09-03 13:31:29 -07002442bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002443
Raj Kamal4393eaa2014-06-06 13:45:20 +05302444 if(!isEnabled() or !mModeOn) {
2445 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302446 return true;
2447 }
2448
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002449 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002450 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002451 sHandleTimeout = true;
2452 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002453
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002454 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002455 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002456
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002457 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2458 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002459 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002460 if(mCurrentFrame.isFBComposed[i]) continue;
2461
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002462 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002463 private_handle_t *hnd = (private_handle_t *)layer->handle;
2464 if(!hnd) {
2465 ALOGE("%s handle null", __FUNCTION__);
2466 return false;
2467 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002468
2469 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2470 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002471 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002472
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002473 int mdpIndex = mCurrentFrame.layerToMDP[i];
2474
Raj Kamal389d6e32014-08-04 14:43:24 +05302475 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302476 {
2477 MdpYUVPipeInfo& pipe_info =
2478 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2479 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2480 ovutils::eDest indexL = pipe_info.lIndex;
2481 ovutils::eDest indexR = pipe_info.rIndex;
2482 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302483 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302484 if(rot) {
2485 rot->queueBuffer(fd, offset);
2486 fd = rot->getDstMemId();
2487 offset = rot->getDstOffset();
2488 }
2489 if(indexL != ovutils::OV_INVALID) {
2490 ovutils::eDest destL = (ovutils::eDest)indexL;
2491 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2492 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2493 if (!ov.queueBuffer(fd, offset, destL)) {
2494 ALOGE("%s: queueBuffer failed for display:%d",
2495 __FUNCTION__, mDpy);
2496 return false;
2497 }
2498 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002499
radhakrishnac9a67412013-09-25 17:40:42 +05302500 if(indexR != ovutils::OV_INVALID) {
2501 ovutils::eDest destR = (ovutils::eDest)indexR;
2502 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2503 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2504 if (!ov.queueBuffer(fd, offset, destR)) {
2505 ALOGE("%s: queueBuffer failed for display:%d",
2506 __FUNCTION__, mDpy);
2507 return false;
2508 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002509 }
2510 }
radhakrishnac9a67412013-09-25 17:40:42 +05302511 else{
2512 MdpPipeInfoSplit& pipe_info =
2513 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2514 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002515
radhakrishnac9a67412013-09-25 17:40:42 +05302516 ovutils::eDest indexL = pipe_info.lIndex;
2517 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002518
radhakrishnac9a67412013-09-25 17:40:42 +05302519 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002520 uint32_t offset = (uint32_t)hnd->offset;
2521 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2522 if (!mDpy && (index != -1)) {
2523 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2524 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002525 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002526 }
radhakrishnac9a67412013-09-25 17:40:42 +05302527
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002528 if(ctx->mAD->draw(ctx, fd, offset)) {
2529 fd = ctx->mAD->getDstFd();
2530 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002531 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002532
radhakrishnac9a67412013-09-25 17:40:42 +05302533 if(rot) {
2534 rot->queueBuffer(fd, offset);
2535 fd = rot->getDstMemId();
2536 offset = rot->getDstOffset();
2537 }
2538
2539 //************* play left mixer **********
2540 if(indexL != ovutils::OV_INVALID) {
2541 ovutils::eDest destL = (ovutils::eDest)indexL;
2542 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2543 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2544 if (!ov.queueBuffer(fd, offset, destL)) {
2545 ALOGE("%s: queueBuffer failed for left mixer",
2546 __FUNCTION__);
2547 return false;
2548 }
2549 }
2550
2551 //************* play right mixer **********
2552 if(indexR != ovutils::OV_INVALID) {
2553 ovutils::eDest destR = (ovutils::eDest)indexR;
2554 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2555 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2556 if (!ov.queueBuffer(fd, offset, destR)) {
2557 ALOGE("%s: queueBuffer failed for right mixer",
2558 __FUNCTION__);
2559 return false;
2560 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002561 }
2562 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002563
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002564 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2565 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002566
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002567 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002568}
Saurabh Shahab47c692014-02-12 18:45:57 -08002569
2570//================MDPCompSrcSplit==============================================
2571bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002572 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002573 private_handle_t *hnd = (private_handle_t *)layer->handle;
2574 hwc_rect_t dst = layer->displayFrame;
2575 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2576 pipe_info.lIndex = ovutils::OV_INVALID;
2577 pipe_info.rIndex = ovutils::OV_INVALID;
2578
2579 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2580 //should have a higher priority than the right one. Pipe priorities are
2581 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002582
Saurabh Shahc62f3982014-03-05 14:28:26 -08002583 Overlay::PipeSpecs pipeSpecs;
2584 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2585 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2586 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2587 pipeSpecs.dpy = mDpy;
2588 pipeSpecs.fb = false;
2589
Saurabh Shahab47c692014-02-12 18:45:57 -08002590 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002591 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002592 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002593 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002594 }
2595
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002596 /* Use 2 pipes IF
2597 a) Layer's crop width is > 2048 or
2598 b) Layer's dest width > 2048 or
2599 c) On primary, driver has indicated with caps to split always. This is
2600 based on an empirically derived value of panel height. Applied only
2601 if the layer's width is > mixer's width
2602 */
2603
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302604 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002605 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302606 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002607 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2608 const uint32_t dstWidth = dst.right - dst.left;
2609 const uint32_t dstHeight = dst.bottom - dst.top;
2610 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002611 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002612 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2613 crop.bottom - crop.top;
2614 //Approximation to actual clock, ignoring the common factors in pipe and
2615 //mixer cases like line_time
2616 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2617 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002618
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002619 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2620 //pipe line length, we are still using 2 pipes. This is fine just because
2621 //this is source split where destination doesn't matter. Evaluate later to
2622 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002623 if(dstWidth > mdpHw.getMaxPipeWidth() or
2624 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002625 (primarySplitAlways and
2626 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002627 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002628 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002629 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002630 }
2631
2632 // Return values
2633 // 1 Left pipe is higher priority, do nothing.
2634 // 0 Pipes of same priority.
2635 //-1 Right pipe is of higher priority, needs swap.
2636 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2637 pipe_info.rIndex) == -1) {
2638 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002639 }
2640 }
2641
2642 return true;
2643}
2644
Saurabh Shahab47c692014-02-12 18:45:57 -08002645int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2646 PipeLayerPair& PipeLayerPair) {
2647 private_handle_t *hnd = (private_handle_t *)layer->handle;
2648 if(!hnd) {
2649 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2650 return -1;
2651 }
2652 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2653 MdpPipeInfoSplit& mdp_info =
2654 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2655 Rotator **rot = &PipeLayerPair.rot;
2656 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002657 eDest lDest = mdp_info.lIndex;
2658 eDest rDest = mdp_info.rIndex;
2659 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2660 hwc_rect_t dst = layer->displayFrame;
2661 int transform = layer->transform;
2662 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002663 int rotFlags = ROT_FLAGS_NONE;
2664 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2665 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2666
2667 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2668 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2669
2670 // Handle R/B swap
2671 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2672 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2673 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2674 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2675 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2676 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002677 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002678 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2679 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002680 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002681 /* Calculate the external display position based on MDP downscale,
2682 ActionSafe, and extorientation features. */
2683 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002684
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002685 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302686 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002687 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002688
2689 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2690 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002691 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002692 }
2693
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002694 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002695 (*rot) = ctx->mRotMgr->getNext();
2696 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002697 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002698 //If the video is using a single pipe, enable BWC
2699 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002700 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2701 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002702 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002703 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002704 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002705 ALOGE("%s: configRotator failed!", __FUNCTION__);
2706 return -1;
2707 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002708 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002709 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002710 }
2711
2712 //If 2 pipes being used, divide layer into half, crop and dst
2713 hwc_rect_t cropL = crop;
2714 hwc_rect_t cropR = crop;
2715 hwc_rect_t dstL = dst;
2716 hwc_rect_t dstR = dst;
2717 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2718 cropL.right = (crop.right + crop.left) / 2;
2719 cropR.left = cropL.right;
2720 sanitizeSourceCrop(cropL, cropR, hnd);
2721
Saurabh Shahb729b192014-08-15 18:04:24 -07002722 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002723 //Swap crops on H flip since 2 pipes are being used
2724 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2725 hwc_rect_t tmp = cropL;
2726 cropL = cropR;
2727 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002728 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002729 }
2730
Saurabh Shahb729b192014-08-15 18:04:24 -07002731 //cropSwap trick: If the src and dst widths are both odd, let us say
2732 //2507, then splitting both into half would cause left width to be 1253
2733 //and right 1254. If crop is swapped because of H flip, this will cause
2734 //left crop width to be 1254, whereas left dst width remains 1253, thus
2735 //inducing a scaling that is unaccounted for. To overcome that we add 1
2736 //to the dst width if there is a cropSwap. So if the original width was
2737 //2507, the left dst width will be 1254. Even if the original width was
2738 //even for ex: 2508, the left dst width will still remain 1254.
2739 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002740 dstR.left = dstL.right;
2741 }
2742
2743 //For the mdp, since either we are pre-rotating or MDP does flips
2744 orient = OVERLAY_TRANSFORM_0;
2745 transform = 0;
2746
2747 //configure left pipe
2748 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002749 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002750 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2751 (ovutils::eBlending) getBlending(layer->blending));
2752
2753 if(configMdp(ctx->mOverlay, pargL, orient,
2754 cropL, dstL, metadata, lDest) < 0) {
2755 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2756 return -1;
2757 }
2758 }
2759
2760 //configure right pipe
2761 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002762 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002763 static_cast<eRotFlags>(rotFlags),
2764 layer->planeAlpha,
2765 (ovutils::eBlending) getBlending(layer->blending));
2766 if(configMdp(ctx->mOverlay, pargR, orient,
2767 cropR, dstR, metadata, rDest) < 0) {
2768 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2769 return -1;
2770 }
2771 }
2772
2773 return 0;
2774}
2775
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002776bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2777 Locker::Autolock _l(ctx->mDrawLock);
2778 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2779 char path[MAX_SYSFS_FILE_PATH];
2780 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2781 int fd = open(path, O_RDONLY);
2782 if(fd < 0) {
2783 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2784 return -1;
2785 }
2786 char value[4];
2787 ssize_t size_read = read(fd, value, sizeof(value)-1);
2788 if(size_read <= 0) {
2789 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2790 close(fd);
2791 return -1;
2792 }
2793 close(fd);
2794 value[size_read] = '\0';
2795 return atoi(value);
2796}
2797
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002798int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2799 Locker::Autolock _l(ctx->mDrawLock);
2800 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2801 char path[MAX_SYSFS_FILE_PATH];
2802 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2803 int fd = open(path, O_WRONLY);
2804 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002805 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002806 return -1;
2807 }
2808 char value[4];
2809 snprintf(value, sizeof(value), "%d", (int)enable);
2810 ssize_t ret = write(fd, value, strlen(value));
2811 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002812 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002813 close(fd);
2814 return -1;
2815 }
2816 close(fd);
2817 sIsPartialUpdateActive = enable;
2818 return 0;
2819}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002820}; //namespace
2821