blob: 6336655a46c5bf8d9adf0cda6297d3100cbed0a9 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
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
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001375 /* Bail out if we dont have any secure RGB layers */
1376 if (!ctx->listStats[mDpy].secureRGBCount) {
1377 reset(ctx);
1378 return false;
1379 }
1380
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001381 mCurrentFrame.reset(numAppLayers);
1382 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1383
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001384 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001385 /* mark secure RGB layers for MDP comp */
1386 updateSecureRGB(ctx, list);
1387
1388 if(mCurrentFrame.mdpCount == 0) {
1389 reset(ctx);
1390 return false;
1391 }
1392
1393 /* find the maximum batch of layers to be marked for framebuffer */
1394 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1395 if(!ret) {
1396 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1397 reset(ctx);
1398 return false;
1399 }
1400
1401 if(sEnableYUVsplit){
1402 adjustForSourceSplit(ctx, list);
1403 }
1404
1405 if(!postHeuristicsHandling(ctx, list)) {
1406 ALOGD_IF(isDebug(), "post heuristic handling failed");
1407 reset(ctx);
1408 return false;
1409 }
1410
1411 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1412 __FUNCTION__);
1413 return true;
1414}
1415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001416/* Checks for conditions where YUV layers cannot be bypassed */
1417bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001418 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001419 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001420 return false;
1421 }
1422
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001423 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001424 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1425 return false;
1426 }
1427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001428 if(isSecuring(ctx, layer)) {
1429 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1430 return false;
1431 }
1432
Saurabh Shah4fdde762013-04-30 18:47:33 -07001433 if(!isValidDimension(ctx, layer)) {
1434 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1435 __FUNCTION__);
1436 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001437 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001438
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001439 if(layer->planeAlpha < 0xFF) {
1440 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1441 in video only mode",
1442 __FUNCTION__);
1443 return false;
1444 }
1445
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001446 return true;
1447}
1448
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001449/* Checks for conditions where Secure RGB layers cannot be bypassed */
1450bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1451 if(isSkipLayer(layer)) {
1452 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1453 __FUNCTION__, mDpy);
1454 return false;
1455 }
1456
1457 if(isSecuring(ctx, layer)) {
1458 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1459 return false;
1460 }
1461
1462 if(not isSupportedForMDPComp(ctx, layer)) {
1463 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1464 __FUNCTION__);
1465 return false;
1466 }
1467 return true;
1468}
1469
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301470/* starts at fromIndex and check for each layer to find
1471 * if it it has overlapping with any Updating layer above it in zorder
1472 * till the end of the batch. returns true if it finds any intersection */
1473bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1474 int fromIndex, int toIndex) {
1475 for(int i = fromIndex; i < toIndex; i++) {
1476 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1477 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1478 return false;
1479 }
1480 }
1481 }
1482 return true;
1483}
1484
1485/* Checks if given layer at targetLayerIndex has any
1486 * intersection with all the updating layers in beween
1487 * fromIndex and toIndex. Returns true if it finds intersectiion */
1488bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1489 int fromIndex, int toIndex, int targetLayerIndex) {
1490 for(int i = fromIndex; i <= toIndex; i++) {
1491 if(!mCurrentFrame.isFBComposed[i]) {
1492 if(areLayersIntersecting(&list->hwLayers[i],
1493 &list->hwLayers[targetLayerIndex])) {
1494 return true;
1495 }
1496 }
1497 }
1498 return false;
1499}
1500
1501int MDPComp::getBatch(hwc_display_contents_1_t* list,
1502 int& maxBatchStart, int& maxBatchEnd,
1503 int& maxBatchCount) {
1504 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301505 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001506 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301507 while (i < mCurrentFrame.layerCount) {
1508 int batchCount = 0;
1509 int batchStart = i;
1510 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001511 /* Adjust batch Z order with the dropped layers so far */
1512 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301513 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301514 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301515 while(i < mCurrentFrame.layerCount) {
1516 if(!mCurrentFrame.isFBComposed[i]) {
1517 if(!batchCount) {
1518 i++;
1519 break;
1520 }
1521 updatingLayersAbove++;
1522 i++;
1523 continue;
1524 } else {
1525 if(mCurrentFrame.drop[i]) {
1526 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001527 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 continue;
1529 } else if(updatingLayersAbove <= 0) {
1530 batchCount++;
1531 batchEnd = i;
1532 i++;
1533 continue;
1534 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1535
1536 // We have a valid updating layer already. If layer-i not
1537 // have overlapping with all updating layers in between
1538 // batch-start and i, then we can add layer i to batch.
1539 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1540 batchCount++;
1541 batchEnd = i;
1542 i++;
1543 continue;
1544 } else if(canPushBatchToTop(list, batchStart, i)) {
1545 //If All the non-updating layers with in this batch
1546 //does not have intersection with the updating layers
1547 //above in z-order, then we can safely move the batch to
1548 //higher z-order. Increment fbZ as it is moving up.
1549 if( firstZReverseIndex < 0) {
1550 firstZReverseIndex = i;
1551 }
1552 batchCount++;
1553 batchEnd = i;
1554 fbZ += updatingLayersAbove;
1555 i++;
1556 updatingLayersAbove = 0;
1557 continue;
1558 } else {
1559 //both failed.start the loop again from here.
1560 if(firstZReverseIndex >= 0) {
1561 i = firstZReverseIndex;
1562 }
1563 break;
1564 }
1565 }
1566 }
1567 }
1568 if(batchCount > maxBatchCount) {
1569 maxBatchCount = batchCount;
1570 maxBatchStart = batchStart;
1571 maxBatchEnd = batchEnd;
1572 fbZOrder = fbZ;
1573 }
1574 }
1575 return fbZOrder;
1576}
1577
1578bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1579 hwc_display_contents_1_t* list) {
1580 /* Idea is to keep as many non-updating(cached) layers in FB and
1581 * send rest of them through MDP. This is done in 2 steps.
1582 * 1. Find the maximum contiguous batch of non-updating layers.
1583 * 2. See if we can improve this batch size for caching by adding
1584 * opaque layers around the batch, if they don't have
1585 * any overlapping with the updating layers in between.
1586 * NEVER mark an updating layer for caching.
1587 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001588
1589 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001590 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001591 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301592 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001593
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001594 /* Nothing is cached. No batching needed */
1595 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001596 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001597 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001598
1599 /* No MDP comp layers, try to use other comp modes */
1600 if(mCurrentFrame.mdpCount == 0) {
1601 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001602 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001603
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301604 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001605
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301606 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001607 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001608 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001609 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301610 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001611 if(!mCurrentFrame.drop[i]){
1612 //If an unsupported layer is being attempted to
1613 //be pulled out we should fail
1614 if(not isSupportedForMDPComp(ctx, layer)) {
1615 return false;
1616 }
1617 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001618 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619 }
1620 }
1621
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301622 // update the frame data
1623 mCurrentFrame.fbZ = fbZ;
1624 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001625 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001626 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627
1628 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301629 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001630
1631 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001632}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001633
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001634void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001635 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001636 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001637 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001638
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001639 for(int i = 0; i < numAppLayers; i++) {
1640 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001641 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001642 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001643 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001644 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001645 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001646 }
1647 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001648
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001649 frame.fbCount = fbCount;
1650 frame.mdpCount = frame.layerCount - frame.fbCount
1651 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001652
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001653 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1654 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001655}
1656
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001657// drop other non-AIV layers from external display list.
1658void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001659 hwc_display_contents_1_t* list) {
1660 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1661 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001662 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001663 mCurrentFrame.dropCount++;
1664 mCurrentFrame.drop[i] = true;
1665 }
1666 }
1667 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1668 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1669 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1670 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1671 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1672 mCurrentFrame.dropCount);
1673}
1674
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001675void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001676 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001677 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1678 for(int index = 0;index < nYuvCount; index++){
1679 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1680 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1681
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001682 if(mCurrentFrame.drop[nYuvIndex]) {
1683 continue;
1684 }
1685
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001687 if(!frame.isFBComposed[nYuvIndex]) {
1688 frame.isFBComposed[nYuvIndex] = true;
1689 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001690 }
1691 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001692 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001693 private_handle_t *hnd = (private_handle_t *)layer->handle;
1694 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001695 frame.isFBComposed[nYuvIndex] = false;
1696 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001697 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001698 }
1699 }
1700 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001701
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001702 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1703 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001704}
1705
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001706void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1707 hwc_display_contents_1_t* list) {
1708 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1709 for(int index = 0;index < nSecureRGBCount; index++){
1710 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1711 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1712
1713 if(!isSecureRGBDoable(ctx, layer)) {
1714 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1715 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1716 mCurrentFrame.fbCount++;
1717 }
1718 } else {
1719 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1720 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1721 mCurrentFrame.fbCount--;
1722 }
1723 }
1724 }
1725
1726 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1727 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1728 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1729 mCurrentFrame.fbCount);
1730}
1731
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001732hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1733 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001734 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001735
1736 /* Update only the region of FB needed for composition */
1737 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1738 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1739 hwc_layer_1_t* layer = &list->hwLayers[i];
1740 hwc_rect_t dst = layer->displayFrame;
1741 fbRect = getUnion(fbRect, dst);
1742 }
1743 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001744 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001745 return fbRect;
1746}
1747
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001748bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1749 hwc_display_contents_1_t* list) {
1750
1751 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001752 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001753 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1754 return false;
1755 }
1756
1757 //Limitations checks
1758 if(!hwLimitationsCheck(ctx, list)) {
1759 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1760 return false;
1761 }
1762
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001763 //Configure framebuffer first if applicable
1764 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001765 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001766 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1767 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001768 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1769 __FUNCTION__);
1770 return false;
1771 }
1772 }
1773
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001774 mCurrentFrame.map();
1775
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001776 if(!allocLayerPipes(ctx, list)) {
1777 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001778 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001779 }
1780
1781 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001782 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001783 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 int mdpIndex = mCurrentFrame.layerToMDP[index];
1785 hwc_layer_1_t* layer = &list->hwLayers[index];
1786
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301787 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1788 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1789 mdpNextZOrder++;
1790 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001791 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1792 cur_pipe->zOrder = mdpNextZOrder++;
1793
radhakrishnac9a67412013-09-25 17:40:42 +05301794 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301795 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301796 if(configure4k2kYuv(ctx, layer,
1797 mCurrentFrame.mdpToLayer[mdpIndex])
1798 != 0 ){
1799 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1800 for layer %d",__FUNCTION__, index);
1801 return false;
1802 }
1803 else{
1804 mdpNextZOrder++;
1805 }
1806 continue;
1807 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001808 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1809 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301810 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001811 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001812 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001813 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814 }
1815
Saurabh Shaha36be922013-12-16 18:18:39 -08001816 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1817 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1818 ,__FUNCTION__, mDpy);
1819 return false;
1820 }
1821
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001822 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001823 return true;
1824}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001825
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001826bool MDPComp::resourceCheck(hwc_context_t* ctx,
1827 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001828 const bool fbUsed = mCurrentFrame.fbCount;
1829 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1830 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1831 return false;
1832 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001833
1834 //Will benefit cases where a video has non-updating background.
1835 if((mDpy > HWC_DISPLAY_PRIMARY) and
1836 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1837 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1838 return false;
1839 }
1840
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001841 // Init rotCount to number of rotate sessions used by other displays
1842 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1843 // Count the number of rotator sessions required for current display
1844 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1845 if(!mCurrentFrame.isFBComposed[index]) {
1846 hwc_layer_1_t* layer = &list->hwLayers[index];
1847 private_handle_t *hnd = (private_handle_t *)layer->handle;
1848 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1849 rotCount++;
1850 }
1851 }
1852 }
1853 // if number of layers to rotate exceeds max rotator sessions, bail out.
1854 if(rotCount > RotMgr::MAX_ROT_SESS) {
1855 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1856 __FUNCTION__, mDpy);
1857 return false;
1858 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001859 return true;
1860}
1861
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301862bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1863 hwc_display_contents_1_t* list) {
1864
1865 //A-family hw limitation:
1866 //If a layer need alpha scaling, MDP can not support.
1867 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1868 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1869 if(!mCurrentFrame.isFBComposed[i] &&
1870 isAlphaScaled( &list->hwLayers[i])) {
1871 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1872 return false;
1873 }
1874 }
1875 }
1876
1877 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1878 //If multiple layers requires downscaling and also they are overlapping
1879 //fall back to GPU since MDSS can not handle it.
1880 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1881 qdutils::MDPVersion::getInstance().is8x26()) {
1882 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1883 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1884 if(!mCurrentFrame.isFBComposed[i] &&
1885 isDownscaleRequired(botLayer)) {
1886 //if layer-i is marked for MDP and needs downscaling
1887 //check if any MDP layer on top of i & overlaps with layer-i
1888 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1889 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1890 if(!mCurrentFrame.isFBComposed[j] &&
1891 isDownscaleRequired(topLayer)) {
1892 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1893 topLayer->displayFrame);
1894 if(isValidRect(r))
1895 return false;
1896 }
1897 }
1898 }
1899 }
1900 }
1901 return true;
1902}
1903
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301904void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1905 //For primary display, set the dynamic refreshrate
1906 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1907 ctx->mUseMetaDataRefreshRate) {
1908 FrameInfo frame;
1909 frame.reset(mCurrentFrame.layerCount);
1910 memset(&frame.drop, 0, sizeof(frame.drop));
1911 frame.dropCount = 0;
1912 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1913 __FUNCTION__);
1914 updateLayerCache(ctx, list, frame);
1915 updateYUV(ctx, list, false /*secure only*/, frame);
1916 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1917 MDPVersion& mdpHw = MDPVersion::getInstance();
1918 if(sIdleFallBack) {
1919 //Set minimum panel refresh rate during idle timeout
1920 refreshRate = mdpHw.getMinFpsSupported();
1921 } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1922 (frame.layerCount == 1)) {
1923 //Set the new fresh rate, if there is only one updating YUV layer
1924 //or there is one single RGB layer with this request
1925 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1926 }
1927 setRefreshRate(ctx, mDpy, refreshRate);
1928 }
1929}
1930
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001931int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001932 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001933 char property[PROPERTY_VALUE_MAX];
1934
Raj Kamal4393eaa2014-06-06 13:45:20 +05301935 if(!ctx || !list) {
1936 ALOGE("%s: Invalid context or list",__FUNCTION__);
1937 mCachedFrame.reset();
1938 return -1;
1939 }
1940
1941 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001942 if(mDpy == HWC_DISPLAY_PRIMARY) {
1943 sSimulationFlags = 0;
1944 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1945 int currentFlags = atoi(property);
1946 if(currentFlags != sSimulationFlags) {
1947 sSimulationFlags = currentFlags;
1948 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1949 sSimulationFlags, sSimulationFlags);
1950 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001951 }
1952 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001953 // reset PTOR
1954 if(!mDpy)
1955 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001956
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301957 //reset old data
1958 mCurrentFrame.reset(numLayers);
1959 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1960 mCurrentFrame.dropCount = 0;
1961
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301962 //Do not cache the information for next draw cycle.
1963 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1964 ALOGI("%s: Unsupported layer count for mdp composition",
1965 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001966 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301967#ifdef DYNAMIC_FPS
1968 setDynRefreshRate(ctx, list);
1969#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001970 return -1;
1971 }
1972
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001973 // Detect the start of animation and fall back to GPU only once to cache
1974 // all the layers in FB and display FB content untill animation completes.
1975 if(ctx->listStats[mDpy].isDisplayAnimating) {
1976 mCurrentFrame.needsRedraw = false;
1977 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1978 mCurrentFrame.needsRedraw = true;
1979 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1980 }
1981 setMDPCompLayerFlags(ctx, list);
1982 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301983#ifdef DYNAMIC_FPS
1984 setDynRefreshRate(ctx, list);
1985#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001986 ret = -1;
1987 return ret;
1988 } else {
1989 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1990 }
1991
Saurabh Shahb39f8152013-08-22 10:21:44 -07001992 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001993 if(isFrameDoable(ctx)) {
1994 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001995 // if AIV Video mode is enabled, drop all non AIV layers from the
1996 // external display list.
1997 if(ctx->listStats[mDpy].mAIVVideoMode) {
1998 dropNonAIVLayers(ctx, list);
1999 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002000
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002001 // if tryFullFrame fails, try to push all video and secure RGB layers
2002 // to MDP for composition.
2003 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002004 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302005 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002006 setMDPCompLayerFlags(ctx, list);
2007 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002008 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002009 reset(ctx);
2010 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2011 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002012 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002013 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2014 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002015 }
2016 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302017 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2018 enablePartialUpdateForMDP3) {
2019 generateROI(ctx, list);
2020 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2021 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2022 }
2023 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002024 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2025 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002026 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002027 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002028
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002029 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002030 ALOGD("GEOMETRY change: %d",
2031 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002032 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002033 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002034 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002035 }
2036
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002037#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302038 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002039#endif
2040
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002041 mCachedFrame.cacheAll(list);
2042 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002043 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002044}
2045
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002046bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302047
2048 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302049 int mdpIndex = mCurrentFrame.layerToMDP[index];
2050 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2051 info.pipeInfo = new MdpYUVPipeInfo;
2052 info.rot = NULL;
2053 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302054
2055 pipe_info.lIndex = ovutils::OV_INVALID;
2056 pipe_info.rIndex = ovutils::OV_INVALID;
2057
Saurabh Shahc62f3982014-03-05 14:28:26 -08002058 Overlay::PipeSpecs pipeSpecs;
2059 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2060 pipeSpecs.needsScaling = true;
2061 pipeSpecs.dpy = mDpy;
2062 pipeSpecs.fb = false;
2063
2064 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302065 if(pipe_info.lIndex == ovutils::OV_INVALID){
2066 bRet = false;
2067 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2068 __FUNCTION__);
2069 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002070 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302071 if(pipe_info.rIndex == ovutils::OV_INVALID){
2072 bRet = false;
2073 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2074 __FUNCTION__);
2075 }
2076 return bRet;
2077}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002078
2079int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2080 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002081 if (ctx->mPtorInfo.isActive()) {
2082 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002083 if (fd < 0) {
2084 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002085 }
2086 }
2087 return fd;
2088}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002089//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002090
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002091void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302092 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002093 //If 4k2k Yuv layer split is possible, and if
2094 //fbz is above 4k2k layer, increment fb zorder by 1
2095 //as we split 4k2k layer and increment zorder for right half
2096 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002097 if(!ctx)
2098 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002099 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302100 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2101 index++) {
2102 if(!mCurrentFrame.isFBComposed[index]) {
2103 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2104 mdpNextZOrder++;
2105 }
2106 mdpNextZOrder++;
2107 hwc_layer_1_t* layer = &list->hwLayers[index];
2108 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302109 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302110 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2111 mCurrentFrame.fbZ += 1;
2112 mdpNextZOrder++;
2113 //As we split 4kx2k yuv layer and program to 2 VG pipes
2114 //(if available) increase mdpcount by 1.
2115 mCurrentFrame.mdpCount++;
2116 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002117 }
2118 }
2119 }
radhakrishnac9a67412013-09-25 17:40:42 +05302120}
2121
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002122/*
2123 * Configures pipe(s) for MDP composition
2124 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002125int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002126 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002127 MdpPipeInfoNonSplit& mdp_info =
2128 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302129 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002130 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002131 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002132
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002133 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2134 __FUNCTION__, layer, zOrder, dest);
2135
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002136 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002137 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002138}
2139
Saurabh Shah88e4d272013-09-03 13:31:29 -07002140bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002141 hwc_display_contents_1_t* list) {
2142 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002143
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002144 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002145
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002146 hwc_layer_1_t* layer = &list->hwLayers[index];
2147 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302148 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002149 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302150 continue;
2151 }
2152 }
2153
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002154 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002155 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002156 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002157 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002158 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002159
Saurabh Shahc62f3982014-03-05 14:28:26 -08002160 Overlay::PipeSpecs pipeSpecs;
2161 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2162 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2163 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2164 (qdutils::MDPVersion::getInstance().is8x26() and
2165 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2166 pipeSpecs.dpy = mDpy;
2167 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002168 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002169
Saurabh Shahc62f3982014-03-05 14:28:26 -08002170 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2171
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002172 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002173 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002174 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002175 }
2176 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002177 return true;
2178}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002179
radhakrishnac9a67412013-09-25 17:40:42 +05302180int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2181 PipeLayerPair& PipeLayerPair) {
2182 MdpYUVPipeInfo& mdp_info =
2183 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2184 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302185 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302186 eDest lDest = mdp_info.lIndex;
2187 eDest rDest = mdp_info.rIndex;
2188
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002189 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302190 lDest, rDest, &PipeLayerPair.rot);
2191}
2192
Saurabh Shah88e4d272013-09-03 13:31:29 -07002193bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002194
Raj Kamal4393eaa2014-06-06 13:45:20 +05302195 if(!isEnabled() or !mModeOn) {
2196 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302197 return true;
2198 }
2199
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002200 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002201 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002202 sHandleTimeout = true;
2203 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002204
2205 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002206 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002207
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002208 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2209 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002210 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002211 if(mCurrentFrame.isFBComposed[i]) continue;
2212
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002213 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002214 private_handle_t *hnd = (private_handle_t *)layer->handle;
2215 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002216 if (!(layer->flags & HWC_COLOR_FILL)) {
2217 ALOGE("%s handle null", __FUNCTION__);
2218 return false;
2219 }
2220 // No PLAY for Color layer
2221 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2222 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002223 }
2224
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002225 int mdpIndex = mCurrentFrame.layerToMDP[i];
2226
Raj Kamal389d6e32014-08-04 14:43:24 +05302227 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302228 {
2229 MdpYUVPipeInfo& pipe_info =
2230 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2231 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2232 ovutils::eDest indexL = pipe_info.lIndex;
2233 ovutils::eDest indexR = pipe_info.rIndex;
2234 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302235 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302236 if(rot) {
2237 rot->queueBuffer(fd, offset);
2238 fd = rot->getDstMemId();
2239 offset = rot->getDstOffset();
2240 }
2241 if(indexL != ovutils::OV_INVALID) {
2242 ovutils::eDest destL = (ovutils::eDest)indexL;
2243 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2244 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2245 if (!ov.queueBuffer(fd, offset, destL)) {
2246 ALOGE("%s: queueBuffer failed for display:%d",
2247 __FUNCTION__, mDpy);
2248 return false;
2249 }
2250 }
2251
2252 if(indexR != ovutils::OV_INVALID) {
2253 ovutils::eDest destR = (ovutils::eDest)indexR;
2254 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2255 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2256 if (!ov.queueBuffer(fd, offset, destR)) {
2257 ALOGE("%s: queueBuffer failed for display:%d",
2258 __FUNCTION__, mDpy);
2259 return false;
2260 }
2261 }
2262 }
2263 else{
2264 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002265 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302266 ovutils::eDest dest = pipe_info.index;
2267 if(dest == ovutils::OV_INVALID) {
2268 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002269 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302270 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002271
radhakrishnac9a67412013-09-25 17:40:42 +05302272 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2273 continue;
2274 }
2275
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002276 int fd = hnd->fd;
2277 uint32_t offset = (uint32_t)hnd->offset;
2278 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2279 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002280 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002281 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002282 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002283 }
2284
radhakrishnac9a67412013-09-25 17:40:42 +05302285 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2286 using pipe: %d", __FUNCTION__, layer,
2287 hnd, dest );
2288
radhakrishnac9a67412013-09-25 17:40:42 +05302289 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2290 if(rot) {
2291 if(!rot->queueBuffer(fd, offset))
2292 return false;
2293 fd = rot->getDstMemId();
2294 offset = rot->getDstOffset();
2295 }
2296
2297 if (!ov.queueBuffer(fd, offset, dest)) {
2298 ALOGE("%s: queueBuffer failed for display:%d ",
2299 __FUNCTION__, mDpy);
2300 return false;
2301 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002302 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002303
2304 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002305 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002306 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002307}
2308
Saurabh Shah88e4d272013-09-03 13:31:29 -07002309//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002310
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002311void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302312 hwc_display_contents_1_t* list){
2313 //if 4kx2k yuv layer is totally present in either in left half
2314 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302315 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302316 if(mCurrentFrame.fbZ >= 0) {
2317 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2318 index++) {
2319 if(!mCurrentFrame.isFBComposed[index]) {
2320 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2321 mdpNextZOrder++;
2322 }
2323 mdpNextZOrder++;
2324 hwc_layer_1_t* layer = &list->hwLayers[index];
2325 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302326 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302327 hwc_rect_t dst = layer->displayFrame;
2328 if((dst.left > lSplit) || (dst.right < lSplit)) {
2329 mCurrentFrame.mdpCount += 1;
2330 }
2331 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2332 mCurrentFrame.fbZ += 1;
2333 mdpNextZOrder++;
2334 }
2335 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002336 }
radhakrishnac9a67412013-09-25 17:40:42 +05302337 }
2338}
2339
Saurabh Shah88e4d272013-09-03 13:31:29 -07002340bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002341 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002342
Saurabh Shahc62f3982014-03-05 14:28:26 -08002343 const int lSplit = getLeftSplit(ctx, mDpy);
2344 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002345 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002346 pipe_info.lIndex = ovutils::OV_INVALID;
2347 pipe_info.rIndex = ovutils::OV_INVALID;
2348
Saurabh Shahc62f3982014-03-05 14:28:26 -08002349 Overlay::PipeSpecs pipeSpecs;
2350 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2351 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2352 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2353 pipeSpecs.dpy = mDpy;
2354 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2355 pipeSpecs.fb = false;
2356
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002357 // Acquire pipe only for the updating half
2358 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2359 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2360
2361 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002362 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002363 if(pipe_info.lIndex == ovutils::OV_INVALID)
2364 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002365 }
2366
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002367 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002368 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2369 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002370 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002371 return false;
2372 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002373
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002374 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002375}
2376
Saurabh Shah88e4d272013-09-03 13:31:29 -07002377bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002378 hwc_display_contents_1_t* list) {
2379 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002380
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002381 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002382
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002383 hwc_layer_1_t* layer = &list->hwLayers[index];
2384 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302385 hwc_rect_t dst = layer->displayFrame;
2386 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302387 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302388 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002389 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302390 continue;
2391 }
2392 }
2393 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002394 int mdpIndex = mCurrentFrame.layerToMDP[index];
2395 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002396 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002397 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002398 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002399
Saurabh Shahc62f3982014-03-05 14:28:26 -08002400 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2401 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2402 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403 return false;
2404 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002405 }
2406 return true;
2407}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002408
radhakrishnac9a67412013-09-25 17:40:42 +05302409int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2410 PipeLayerPair& PipeLayerPair) {
2411 const int lSplit = getLeftSplit(ctx, mDpy);
2412 hwc_rect_t dst = layer->displayFrame;
2413 if((dst.left > lSplit)||(dst.right < lSplit)){
2414 MdpYUVPipeInfo& mdp_info =
2415 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2416 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302417 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302418 eDest lDest = mdp_info.lIndex;
2419 eDest rDest = mdp_info.rIndex;
2420
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002421 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302422 lDest, rDest, &PipeLayerPair.rot);
2423 }
2424 else{
2425 return configure(ctx, layer, PipeLayerPair);
2426 }
2427}
2428
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002429/*
2430 * Configures pipe(s) for MDP composition
2431 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002432int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002433 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002434 MdpPipeInfoSplit& mdp_info =
2435 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002436 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302437 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002438 eDest lDest = mdp_info.lIndex;
2439 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002440
2441 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002442 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002443
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002444 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002445 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002446}
2447
Saurabh Shah88e4d272013-09-03 13:31:29 -07002448bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002449
Raj Kamal4393eaa2014-06-06 13:45:20 +05302450 if(!isEnabled() or !mModeOn) {
2451 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302452 return true;
2453 }
2454
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002455 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002456 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002457 sHandleTimeout = true;
2458 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002459
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002460 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002461 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002462
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002463 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2464 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002465 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002466 if(mCurrentFrame.isFBComposed[i]) continue;
2467
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002468 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002469 private_handle_t *hnd = (private_handle_t *)layer->handle;
2470 if(!hnd) {
2471 ALOGE("%s handle null", __FUNCTION__);
2472 return false;
2473 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002474
2475 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2476 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002477 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002478
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002479 int mdpIndex = mCurrentFrame.layerToMDP[i];
2480
Raj Kamal389d6e32014-08-04 14:43:24 +05302481 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302482 {
2483 MdpYUVPipeInfo& pipe_info =
2484 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2485 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2486 ovutils::eDest indexL = pipe_info.lIndex;
2487 ovutils::eDest indexR = pipe_info.rIndex;
2488 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302489 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302490 if(rot) {
2491 rot->queueBuffer(fd, offset);
2492 fd = rot->getDstMemId();
2493 offset = rot->getDstOffset();
2494 }
2495 if(indexL != ovutils::OV_INVALID) {
2496 ovutils::eDest destL = (ovutils::eDest)indexL;
2497 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2498 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2499 if (!ov.queueBuffer(fd, offset, destL)) {
2500 ALOGE("%s: queueBuffer failed for display:%d",
2501 __FUNCTION__, mDpy);
2502 return false;
2503 }
2504 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002505
radhakrishnac9a67412013-09-25 17:40:42 +05302506 if(indexR != ovutils::OV_INVALID) {
2507 ovutils::eDest destR = (ovutils::eDest)indexR;
2508 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2509 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2510 if (!ov.queueBuffer(fd, offset, destR)) {
2511 ALOGE("%s: queueBuffer failed for display:%d",
2512 __FUNCTION__, mDpy);
2513 return false;
2514 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002515 }
2516 }
radhakrishnac9a67412013-09-25 17:40:42 +05302517 else{
2518 MdpPipeInfoSplit& pipe_info =
2519 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2520 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002521
radhakrishnac9a67412013-09-25 17:40:42 +05302522 ovutils::eDest indexL = pipe_info.lIndex;
2523 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002524
radhakrishnac9a67412013-09-25 17:40:42 +05302525 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002526 uint32_t offset = (uint32_t)hnd->offset;
2527 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2528 if (!mDpy && (index != -1)) {
2529 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2530 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002531 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002532 }
radhakrishnac9a67412013-09-25 17:40:42 +05302533
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002534 if(ctx->mAD->draw(ctx, fd, offset)) {
2535 fd = ctx->mAD->getDstFd();
2536 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002537 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002538
radhakrishnac9a67412013-09-25 17:40:42 +05302539 if(rot) {
2540 rot->queueBuffer(fd, offset);
2541 fd = rot->getDstMemId();
2542 offset = rot->getDstOffset();
2543 }
2544
2545 //************* play left mixer **********
2546 if(indexL != ovutils::OV_INVALID) {
2547 ovutils::eDest destL = (ovutils::eDest)indexL;
2548 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2549 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2550 if (!ov.queueBuffer(fd, offset, destL)) {
2551 ALOGE("%s: queueBuffer failed for left mixer",
2552 __FUNCTION__);
2553 return false;
2554 }
2555 }
2556
2557 //************* play right mixer **********
2558 if(indexR != ovutils::OV_INVALID) {
2559 ovutils::eDest destR = (ovutils::eDest)indexR;
2560 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2561 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2562 if (!ov.queueBuffer(fd, offset, destR)) {
2563 ALOGE("%s: queueBuffer failed for right mixer",
2564 __FUNCTION__);
2565 return false;
2566 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002567 }
2568 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002569
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002570 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2571 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002572
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002573 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002574}
Saurabh Shahab47c692014-02-12 18:45:57 -08002575
2576//================MDPCompSrcSplit==============================================
2577bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002578 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002579 private_handle_t *hnd = (private_handle_t *)layer->handle;
2580 hwc_rect_t dst = layer->displayFrame;
2581 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2582 pipe_info.lIndex = ovutils::OV_INVALID;
2583 pipe_info.rIndex = ovutils::OV_INVALID;
2584
2585 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2586 //should have a higher priority than the right one. Pipe priorities are
2587 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002588
Saurabh Shahc62f3982014-03-05 14:28:26 -08002589 Overlay::PipeSpecs pipeSpecs;
2590 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2591 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2592 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2593 pipeSpecs.dpy = mDpy;
2594 pipeSpecs.fb = false;
2595
Saurabh Shahab47c692014-02-12 18:45:57 -08002596 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002597 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002598 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002599 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002600 }
2601
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002602 /* Use 2 pipes IF
2603 a) Layer's crop width is > 2048 or
2604 b) Layer's dest width > 2048 or
2605 c) On primary, driver has indicated with caps to split always. This is
2606 based on an empirically derived value of panel height. Applied only
2607 if the layer's width is > mixer's width
2608 */
2609
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302610 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002611 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302612 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002613 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2614 const uint32_t dstWidth = dst.right - dst.left;
2615 const uint32_t dstHeight = dst.bottom - dst.top;
2616 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002617 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002618 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2619 crop.bottom - crop.top;
2620 //Approximation to actual clock, ignoring the common factors in pipe and
2621 //mixer cases like line_time
2622 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2623 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002624
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002625 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2626 //pipe line length, we are still using 2 pipes. This is fine just because
2627 //this is source split where destination doesn't matter. Evaluate later to
2628 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002629 if(dstWidth > mdpHw.getMaxPipeWidth() or
2630 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002631 (primarySplitAlways and
2632 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002633 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002634 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002635 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002636 }
2637
2638 // Return values
2639 // 1 Left pipe is higher priority, do nothing.
2640 // 0 Pipes of same priority.
2641 //-1 Right pipe is of higher priority, needs swap.
2642 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2643 pipe_info.rIndex) == -1) {
2644 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002645 }
2646 }
2647
2648 return true;
2649}
2650
Saurabh Shahab47c692014-02-12 18:45:57 -08002651int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2652 PipeLayerPair& PipeLayerPair) {
2653 private_handle_t *hnd = (private_handle_t *)layer->handle;
2654 if(!hnd) {
2655 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2656 return -1;
2657 }
2658 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2659 MdpPipeInfoSplit& mdp_info =
2660 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2661 Rotator **rot = &PipeLayerPair.rot;
2662 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002663 eDest lDest = mdp_info.lIndex;
2664 eDest rDest = mdp_info.rIndex;
2665 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2666 hwc_rect_t dst = layer->displayFrame;
2667 int transform = layer->transform;
2668 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002669 int rotFlags = ROT_FLAGS_NONE;
2670 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2671 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2672
2673 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2674 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2675
2676 // Handle R/B swap
2677 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2678 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2679 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2680 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2681 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2682 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002683 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002684 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2685 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002686 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002687 /* Calculate the external display position based on MDP downscale,
2688 ActionSafe, and extorientation features. */
2689 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002690
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002691 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302692 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002693 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002694
2695 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2696 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002697 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002698 }
2699
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002700 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002701 (*rot) = ctx->mRotMgr->getNext();
2702 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002703 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002704 //If the video is using a single pipe, enable BWC
2705 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002706 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2707 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002708 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002709 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002710 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002711 ALOGE("%s: configRotator failed!", __FUNCTION__);
2712 return -1;
2713 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002714 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002715 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002716 }
2717
2718 //If 2 pipes being used, divide layer into half, crop and dst
2719 hwc_rect_t cropL = crop;
2720 hwc_rect_t cropR = crop;
2721 hwc_rect_t dstL = dst;
2722 hwc_rect_t dstR = dst;
2723 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2724 cropL.right = (crop.right + crop.left) / 2;
2725 cropR.left = cropL.right;
2726 sanitizeSourceCrop(cropL, cropR, hnd);
2727
Saurabh Shahb729b192014-08-15 18:04:24 -07002728 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002729 //Swap crops on H flip since 2 pipes are being used
2730 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2731 hwc_rect_t tmp = cropL;
2732 cropL = cropR;
2733 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002734 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002735 }
2736
Saurabh Shahb729b192014-08-15 18:04:24 -07002737 //cropSwap trick: If the src and dst widths are both odd, let us say
2738 //2507, then splitting both into half would cause left width to be 1253
2739 //and right 1254. If crop is swapped because of H flip, this will cause
2740 //left crop width to be 1254, whereas left dst width remains 1253, thus
2741 //inducing a scaling that is unaccounted for. To overcome that we add 1
2742 //to the dst width if there is a cropSwap. So if the original width was
2743 //2507, the left dst width will be 1254. Even if the original width was
2744 //even for ex: 2508, the left dst width will still remain 1254.
2745 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002746 dstR.left = dstL.right;
2747 }
2748
2749 //For the mdp, since either we are pre-rotating or MDP does flips
2750 orient = OVERLAY_TRANSFORM_0;
2751 transform = 0;
2752
2753 //configure left pipe
2754 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002755 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002756 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2757 (ovutils::eBlending) getBlending(layer->blending));
2758
2759 if(configMdp(ctx->mOverlay, pargL, orient,
2760 cropL, dstL, metadata, lDest) < 0) {
2761 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2762 return -1;
2763 }
2764 }
2765
2766 //configure right pipe
2767 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002768 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002769 static_cast<eRotFlags>(rotFlags),
2770 layer->planeAlpha,
2771 (ovutils::eBlending) getBlending(layer->blending));
2772 if(configMdp(ctx->mOverlay, pargR, orient,
2773 cropR, dstR, metadata, rDest) < 0) {
2774 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2775 return -1;
2776 }
2777 }
2778
2779 return 0;
2780}
2781
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002782bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2783 Locker::Autolock _l(ctx->mDrawLock);
2784 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2785 char path[MAX_SYSFS_FILE_PATH];
2786 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2787 int fd = open(path, O_RDONLY);
2788 if(fd < 0) {
2789 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2790 return -1;
2791 }
2792 char value[4];
2793 ssize_t size_read = read(fd, value, sizeof(value)-1);
2794 if(size_read <= 0) {
2795 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2796 close(fd);
2797 return -1;
2798 }
2799 close(fd);
2800 value[size_read] = '\0';
2801 return atoi(value);
2802}
2803
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002804int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2805 Locker::Autolock _l(ctx->mDrawLock);
2806 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2807 char path[MAX_SYSFS_FILE_PATH];
2808 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2809 int fd = open(path, O_WRONLY);
2810 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002811 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002812 return -1;
2813 }
2814 char value[4];
2815 snprintf(value, sizeof(value), "%d", (int)enable);
2816 ssize_t ret = write(fd, value, strlen(value));
2817 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002818 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002819 close(fd);
2820 return -1;
2821 }
2822 close(fd);
2823 sIsPartialUpdateActive = enable;
2824 return 0;
2825}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002826}; //namespace
2827