blob: 79a42492c7b1588cad8671aa4d31d81185553b97 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070022#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070029#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Saurabh Shah59562ff2014-09-30 16:13:12 -070040IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070041bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070047int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080050int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053051bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070052bool MDPComp::sIsPartialUpdateActive = true;
Saurabh Shah88e4d272013-09-03 13:31:29 -070053MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070054 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
55 sSrcSplitEnabled = true;
56 return new MDPCompSrcSplit(dpy);
57 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070058 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080059 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070060 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080061}
62
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080063MDPComp::MDPComp(int dpy):mDpy(dpy){};
64
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070065void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080066{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070067 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
68 return;
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070071 (mDpy == 0) ? "\"PRIMARY\"" :
72 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070073 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
74 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080075 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
76 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
77 (mCurrentFrame.needsRedraw? "YES" : "NO"),
78 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070079 if(isDisplaySplit(ctx, mDpy)) {
80 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
81 "Right: [%d, %d, %d, %d] \n",
82 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
83 ctx->listStats[mDpy].lRoi.right,
84 ctx->listStats[mDpy].lRoi.bottom,
85 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
86 ctx->listStats[mDpy].rRoi.right,
87 ctx->listStats[mDpy].rRoi.bottom);
88 } else {
89 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
90 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
91 ctx->listStats[mDpy].lRoi.right,
92 ctx->listStats[mDpy].lRoi.bottom);
93 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080094 dumpsys_log(buf," --------------------------------------------- \n");
95 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
96 dumpsys_log(buf," --------------------------------------------- \n");
97 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
98 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
99 index,
100 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700101 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700103 (mCurrentFrame.drop[index] ? "DROP" :
104 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800105 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
106 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
107 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800108}
109
110bool MDPComp::init(hwc_context_t *ctx) {
111
112 if(!ctx) {
113 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
114 return false;
115 }
116
Saurabh Shah59562ff2014-09-30 16:13:12 -0700117 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800118
119 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530120 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
121 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800122 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
123 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800124 sEnabled = true;
125 }
126
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700127 sEnableMixedMode = true;
128 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
131 sEnableMixedMode = false;
132 }
133
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700134 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
135
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800136 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700137 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700138 int val = atoi(property);
139 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700140 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800141 }
142
Saurabh Shahacec8e42014-11-25 11:07:04 -0800143 /* Maximum layers allowed to use MDP on secondary panels. If property
144 * doesn't exist, default to 1. Using the property it can be set to 0 or
145 * more.
146 */
147 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
148 int val = atoi(property);
149 sMaxSecLayers = (val >= 0) ? val : 1;
150 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
151 }
152
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400153 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700154 sIdleInvalidator = IdleInvalidator::getInstance();
155 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
156 delete sIdleInvalidator;
157 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400158 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800159 }
radhakrishnac9a67412013-09-25 17:40:42 +0530160
Saurabh Shah7c727642014-06-02 15:47:14 -0700161 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700162 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700163 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
164 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
165 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530166 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530167 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700168
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530169 bool defaultPTOR = false;
170 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
171 //8x16 and 8x39 targets by default
172 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
173 (qdutils::MDPVersion::getInstance().is8x16() ||
174 qdutils::MDPVersion::getInstance().is8x39())) {
175 defaultPTOR = true;
176 }
177
178 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
179 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700180 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
181 HWC_DISPLAY_PRIMARY);
182 }
183
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530184 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
185 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
186 enablePartialUpdateForMDP3 = true;
187 }
188
189 if(!enablePartialUpdateForMDP3 &&
190 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
191 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
192 enablePartialUpdateForMDP3 = true;
193 }
194
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800195 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
196
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700197 return true;
198}
199
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800200void MDPComp::reset(hwc_context_t *ctx) {
201 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700202 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800203 ctx->mOverlay->clear(mDpy);
204 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700205}
206
Raj Kamal4393eaa2014-06-06 13:45:20 +0530207void MDPComp::reset() {
208 sHandleTimeout = false;
209 mModeOn = false;
210}
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212void MDPComp::timeout_handler(void *udata) {
213 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
214
215 if(!ctx) {
216 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
217 return;
218 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800219 Locker::Autolock _l(ctx->mDrawLock);
220 // Handle timeout event only if the previous composition is MDP or MIXED.
221 if(!sHandleTimeout) {
222 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
223 return;
224 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700225 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700226 ALOGE("%s: HWC proc not registered", __FUNCTION__);
227 return;
228 }
229 sIdleFallBack = true;
230 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700231 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232}
233
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700234void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
235 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800236 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700237 if(value > maxSupported) {
238 ALOGW("%s: Input exceeds max value supported. Setting to"
239 "max value: %d", __FUNCTION__, maxSupported);
240 }
241 sMaxPipesPerMixer = min(value, maxSupported);
242}
243
Saurabh Shah59562ff2014-09-30 16:13:12 -0700244void MDPComp::setIdleTimeout(const uint32_t& timeout) {
245 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
246
247 if(sIdleInvalidator) {
248 if(timeout <= ONE_REFRESH_PERIOD_MS) {
249 //If the specified timeout is < 1 draw cycle worth, "virtually"
250 //disable idle timeout. The ideal way for clients to disable
251 //timeout is to set it to 0
252 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
253 ALOGI("Disabled idle timeout");
254 return;
255 }
256 sIdleInvalidator->setIdleTimeout(timeout);
257 ALOGI("Idle timeout set to %u", timeout);
258 } else {
259 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
260 }
261}
262
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800263void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264 hwc_display_contents_1_t* list) {
265 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800266
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800267 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800268 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800269 if(!mCurrentFrame.isFBComposed[index]) {
270 layerProp[index].mFlags |= HWC_MDPCOMP;
271 layer->compositionType = HWC_OVERLAY;
272 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800273 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700274 /* Drop the layer when its already present in FB OR when it lies
275 * outside frame's ROI */
276 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800277 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700278 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800279 }
280 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700281}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500282
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800283void MDPComp::setRedraw(hwc_context_t *ctx,
284 hwc_display_contents_1_t* list) {
285 mCurrentFrame.needsRedraw = false;
286 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
287 (list->flags & HWC_GEOMETRY_CHANGED) ||
288 isSkipPresent(ctx, mDpy)) {
289 mCurrentFrame.needsRedraw = true;
290 }
291}
292
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800293MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700294 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800297
Saurabh Shahaa236822013-04-24 18:07:26 -0700298void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700299 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300 if(mdpToLayer[i].pipeInfo) {
301 delete mdpToLayer[i].pipeInfo;
302 mdpToLayer[i].pipeInfo = NULL;
303 //We dont own the rotator
304 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800305 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800306 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800307
308 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
309 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700310 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800311
Saurabh Shahaa236822013-04-24 18:07:26 -0700312 layerCount = numLayers;
313 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800314 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700315 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800316 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800317}
318
Saurabh Shahaa236822013-04-24 18:07:26 -0700319void MDPComp::FrameInfo::map() {
320 // populate layer and MDP maps
321 int mdpIdx = 0;
322 for(int idx = 0; idx < layerCount; idx++) {
323 if(!isFBComposed[idx]) {
324 mdpToLayer[mdpIdx].listIndex = idx;
325 layerToMDP[idx] = mdpIdx++;
326 }
327 }
328}
329
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330MDPComp::LayerCache::LayerCache() {
331 reset();
332}
333
334void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700335 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530336 memset(&isFBComposed, true, sizeof(isFBComposed));
337 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800338 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700339}
340
341void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530342 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700343 for(int i = 0; i < numAppLayers; i++) {
344 hnd[i] = list->hwLayers[i].handle;
345 }
346}
347
348void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700349 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530350 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
351 memcpy(&drop, &curFrame.drop, sizeof(drop));
352}
353
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800354bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
355 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530356 if(layerCount != curFrame.layerCount)
357 return false;
358 for(int i = 0; i < curFrame.layerCount; i++) {
359 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
360 (curFrame.drop[i] != drop[i])) {
361 return false;
362 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800363 if(curFrame.isFBComposed[i] &&
364 (hnd[i] != list->hwLayers[i].handle)){
365 return false;
366 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530367 }
368 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800369}
370
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700371bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
372 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800373 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700374 (not isValidDimension(ctx,layer))
375 //More conditions here, SKIP, sRGB+Blend etc
376 ) {
377 return false;
378 }
379 return true;
380}
381
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530382bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800383 private_handle_t *hnd = (private_handle_t *)layer->handle;
384
385 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700386 if (layer->flags & HWC_COLOR_FILL) {
387 // Color layer
388 return true;
389 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700390 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800391 return false;
392 }
393
Naseer Ahmede850a802013-09-06 13:12:52 -0400394 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400395 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400396 return false;
397
Saurabh Shah62e1d732013-09-17 10:44:05 -0700398 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700400 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700401 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
402 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700403 int dst_w = dst.right - dst.left;
404 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800405 float w_scale = ((float)crop_w / (float)dst_w);
406 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530407 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700408
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800409 /* Workaround for MDP HW limitation in DSI command mode panels where
410 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
411 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530412 * There also is a HW limilation in MDP, minimum block size is 2x2
413 * Fallback to GPU if height is less than 2.
414 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700415 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800416 return false;
417
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800418 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530419 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800420 const float w_dscale = w_scale;
421 const float h_dscale = h_scale;
422
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800423 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700424
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530425 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700426 /* On targets that doesnt support Decimation (eg.,8x26)
427 * maximum downscale support is overlay pipe downscale.
428 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400429 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530430 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700431 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800432 return false;
433 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700434 // Decimation on macrotile format layers is not supported.
435 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530436 /* Bail out if
437 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700438 * 2. exceeds maximum downscale limit
439 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400440 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530441 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700442 w_dscale > maxMDPDownscale ||
443 h_dscale > maxMDPDownscale) {
444 return false;
445 }
446 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800447 return false;
448 }
449 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700450 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700451 return false;
452 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700453 }
454
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800455 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530456 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800457 const float w_uscale = 1.0f / w_scale;
458 const float h_uscale = 1.0f / h_scale;
459
460 if(w_uscale > upscale || h_uscale > upscale)
461 return false;
462 }
463
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800464 return true;
465}
466
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800467bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700468 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800469
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800470 if(!isEnabled()) {
471 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700472 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530473 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530474 qdutils::MDPVersion::getInstance().is8x16() ||
475 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800476 ctx->mVideoTransFlag &&
477 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700478 //1 Padding round to shift pipes across mixers
479 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
480 __FUNCTION__);
481 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700482 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
483 /* TODO: freeing up all the resources only for the targets having total
484 number of pipes < 8. Need to analyze number of VIG pipes used
485 for primary in previous draw cycle and accordingly decide
486 whether to fall back to full GPU comp or video only comp
487 */
488 if(isSecondaryConfiguring(ctx)) {
489 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
490 __FUNCTION__);
491 ret = false;
492 } else if(ctx->isPaddingRound) {
493 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
494 __FUNCTION__,mDpy);
495 ret = false;
496 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800497 } else if (ctx->isDMAStateChanging) {
498 // Bail out if a padding round has been invoked in order to switch DMA
499 // state to block mode. We need this to cater for the case when a layer
500 // requires rotation in the current frame.
501 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
502 __FUNCTION__);
503 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700504 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800505
Saurabh Shahaa236822013-04-24 18:07:26 -0700506 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800507}
508
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
510 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
511 fbRect = getIntersection(fbRect, roi);
512}
513
514/* 1) Identify layers that are not visible or lying outside the updating ROI and
515 * drop them from composition.
516 * 2) If we have a scaling layer which needs cropping against generated
517 * ROI, reset ROI to full resolution. */
518bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
519 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700520 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800521 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800522
523 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800524 if(!isValidRect(visibleRect)) {
525 mCurrentFrame.drop[i] = true;
526 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800527 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800528 }
529
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700530 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700531 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800532 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700533
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534 if(!isValidRect(res)) {
535 mCurrentFrame.drop[i] = true;
536 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800537 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700538 /* Reset frame ROI when any layer which needs scaling also needs ROI
539 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800541 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700542 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
543 mCurrentFrame.dropCount = 0;
544 return false;
545 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800546
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800547 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530548 if (layer->blending == HWC_BLENDING_NONE &&
549 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800550 visibleRect = deductRect(visibleRect, res);
551 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700552 }
553 return true;
554}
555
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800556/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
557 * are updating. If DirtyRegion is applicable, calculate it by accounting all
558 * the changing layer's dirtyRegion. */
559void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
560 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700561 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800562 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700563 return;
564
565 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800566 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
567 (int)ctx->dpyAttr[mDpy].yres};
568
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700569 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800570 hwc_layer_1_t* layer = &list->hwLayers[index];
571 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800572 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700573 hwc_rect_t dst = layer->displayFrame;
574 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800576#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700578 {
579 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
580 int x_off = dst.left - src.left;
581 int y_off = dst.top - src.top;
582 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
583 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800584#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800585
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800586 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700587 }
588 }
589
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800590 /* No layer is updating. Still SF wants a refresh.*/
591 if(!isValidRect(roi))
592 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800593
594 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800595 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800596
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800597 ctx->listStats[mDpy].lRoi = roi;
598 if(!validateAndApplyROI(ctx, list))
599 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700600
601 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800602 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
603 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
604}
605
606void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
607 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
608 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
609
610 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
611 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
612 fbRect = getUnion(l_fbRect, r_fbRect);
613}
614/* 1) Identify layers that are not visible or lying outside BOTH the updating
615 * ROI's and drop them from composition. If a layer is spanning across both
616 * the halves of the screen but needed by only ROI, the non-contributing
617 * half will not be programmed for MDP.
618 * 2) If we have a scaling layer which needs cropping against generated
619 * ROI, reset ROI to full resolution. */
620bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
621 hwc_display_contents_1_t* list) {
622
623 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
624
625 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
626 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
627
628 for(int i = numAppLayers - 1; i >= 0; i--){
629 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
630 {
631 mCurrentFrame.drop[i] = true;
632 mCurrentFrame.dropCount++;
633 continue;
634 }
635
636 const hwc_layer_1_t* layer = &list->hwLayers[i];
637 hwc_rect_t dstRect = layer->displayFrame;
638
639 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
640 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
641 hwc_rect_t res = getUnion(l_res, r_res);
642
643 if(!isValidRect(l_res) && !isValidRect(r_res)) {
644 mCurrentFrame.drop[i] = true;
645 mCurrentFrame.dropCount++;
646 } else {
647 /* Reset frame ROI when any layer which needs scaling also needs ROI
648 * cropping */
649 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
650 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
651 mCurrentFrame.dropCount = 0;
652 return false;
653 }
654
radhakrishna4efbdd62014-11-03 13:19:27 +0530655 if (layer->blending == HWC_BLENDING_NONE &&
656 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800657 visibleRectL = deductRect(visibleRectL, l_res);
658 visibleRectR = deductRect(visibleRectR, r_res);
659 }
660 }
661 }
662 return true;
663}
664/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
665 * are updating. If DirtyRegion is applicable, calculate it by accounting all
666 * the changing layer's dirtyRegion. */
667void MDPCompSplit::generateROI(hwc_context_t *ctx,
668 hwc_display_contents_1_t* list) {
669 if(!canPartialUpdate(ctx, list))
670 return;
671
672 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
673 int lSplit = getLeftSplit(ctx, mDpy);
674
675 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
676 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
677
678 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
679 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
680
681 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
682 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
683
684 for(int index = 0; index < numAppLayers; index++ ) {
685 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800686 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800687 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800688 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700689 hwc_rect_t dst = layer->displayFrame;
690 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800691
692#ifdef QCOM_BSP
693 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700694 {
695 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
696 int x_off = dst.left - src.left;
697 int y_off = dst.top - src.top;
698 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
699 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800700#endif
701
702 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
703 if(isValidRect(l_dst))
704 l_roi = getUnion(l_roi, l_dst);
705
706 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
707 if(isValidRect(r_dst))
708 r_roi = getUnion(r_roi, r_dst);
709 }
710 }
711
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700712 /* For panels that cannot accept commands in both the interfaces, we cannot
713 * send two ROI's (for each half). We merge them into single ROI and split
714 * them across lSplit for MDP mixer use. The ROI's will be merged again
715 * finally before udpating the panel in the driver. */
716 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
717 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
718 l_roi = getIntersection(temp_roi, l_frame);
719 r_roi = getIntersection(temp_roi, r_frame);
720 }
721
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800722 /* No layer is updating. Still SF wants a refresh. */
723 if(!isValidRect(l_roi) && !isValidRect(r_roi))
724 return;
725
726 l_roi = getSanitizeROI(l_roi, l_frame);
727 r_roi = getSanitizeROI(r_roi, r_frame);
728
729 ctx->listStats[mDpy].lRoi = l_roi;
730 ctx->listStats[mDpy].rRoi = r_roi;
731
732 if(!validateAndApplyROI(ctx, list))
733 resetROI(ctx, mDpy);
734
735 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
736 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
737 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
738 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
739 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
740 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700741}
742
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800743/* Checks for conditions where all the layers marked for MDP comp cannot be
744 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800745bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800746 hwc_display_contents_1_t* list){
747
Saurabh Shahaa236822013-04-24 18:07:26 -0700748 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800749
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700750 // Fall back to video only composition, if AIV video mode is enabled
751 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700752 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
753 __FUNCTION__, mDpy);
754 return false;
755 }
756
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400757 // No Idle fall back, if secure display or secure RGB layers are present or
758 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700759 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400760 !ctx->listStats[mDpy].secureRGBCount) &&
761 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700762 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
763 return false;
764 }
765
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800766 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700767 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
768 __FUNCTION__,
769 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800770 return false;
771 }
772
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700773 // if secondary is configuring or Padding round, fall back to video only
774 // composition and release all assigned non VIG pipes from primary.
775 if(isSecondaryConfiguring(ctx)) {
776 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
777 __FUNCTION__);
778 return false;
779 } else if(ctx->isPaddingRound) {
780 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
781 __FUNCTION__,mDpy);
782 return false;
783 }
784
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700785 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800786 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700787 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800788 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
789 return false;
790 }
791
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800792 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800793 hwc_layer_1_t* layer = &list->hwLayers[i];
794 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800795
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800796 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700797 if(!canUseRotator(ctx, mDpy)) {
798 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
799 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700800 return false;
801 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800802 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530803
804 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
805 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800806 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700807 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530808 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
809 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
810 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800811 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700812
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700813 if(ctx->mAD->isDoable()) {
814 return false;
815 }
816
Saurabh Shahaa236822013-04-24 18:07:26 -0700817 //If all above hard conditions are met we can do full or partial MDP comp.
818 bool ret = false;
819 if(fullMDPComp(ctx, list)) {
820 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700821 } else if(fullMDPCompWithPTOR(ctx, list)) {
822 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700823 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700824 ret = true;
825 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530826
Saurabh Shahaa236822013-04-24 18:07:26 -0700827 return ret;
828}
829
830bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700831
832 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
833 return false;
834
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700835 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
836 for(int i = 0; i < numAppLayers; i++) {
837 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700838 if(not mCurrentFrame.drop[i] and
839 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700840 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
841 return false;
842 }
843 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800844
Saurabh Shahaa236822013-04-24 18:07:26 -0700845 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700846 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
847 sizeof(mCurrentFrame.isFBComposed));
848 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
849 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700850
Raj Kamal389d6e32014-08-04 14:43:24 +0530851 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800852 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530853 }
854
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800855 if(!postHeuristicsHandling(ctx, list)) {
856 ALOGD_IF(isDebug(), "post heuristic handling failed");
857 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700858 return false;
859 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700860 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
861 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700862 return true;
863}
864
Sushil Chauhandefd3522014-05-13 18:17:12 -0700865/* Full MDP Composition with Peripheral Tiny Overlap Removal.
866 * MDP bandwidth limitations can be avoided, if the overlap region
867 * covered by the smallest layer at a higher z-order, gets composed
868 * by Copybit on a render buffer, which can be queued to MDP.
869 */
870bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
871 hwc_display_contents_1_t* list) {
872
873 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
874 const int stagesForMDP = min(sMaxPipesPerMixer,
875 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
876
877 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700878 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700879 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
880 return false;
881 }
882
883 // Frame level checks
884 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
885 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
886 isSecurePresent(ctx, mDpy)) {
887 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
888 return false;
889 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700890 // MDP comp checks
891 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700892 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700893 if(not isSupportedForMDPComp(ctx, layer)) {
894 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
895 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700896 }
897 }
898
Sushil Chauhandefd3522014-05-13 18:17:12 -0700899 /* We cannot use this composition mode, if:
900 1. A below layer needs scaling.
901 2. Overlap is not peripheral to display.
902 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700903 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700904 */
905
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
907 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
908 memset(overlapRect, 0, sizeof(overlapRect));
909 int layerPixelCount, minPixelCount = 0;
910 int numPTORLayersFound = 0;
911 for (int i = numAppLayers-1; (i >= 0 &&
912 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700913 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700914 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700916 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
917 // PTOR layer should be peripheral and cannot have transform
918 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
919 has90Transform(layer)) {
920 continue;
921 }
922 if((3 * (layerPixelCount + minPixelCount)) >
923 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
924 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
925 continue;
926 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700927 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700928 for (int j = i-1; j >= 0; j--) {
929 // Check if the layers below this layer qualifies for PTOR comp
930 hwc_layer_1_t* layer = &list->hwLayers[j];
931 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700932 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700933 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700934 if (isValidRect(getIntersection(dispFrame, disFrame))) {
935 if (has90Transform(layer) || needsScaling(layer)) {
936 found = false;
937 break;
938 }
939 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700940 }
941 }
942 // Store the minLayer Index
943 if(found) {
944 minLayerIndex[numPTORLayersFound] = i;
945 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
946 minPixelCount += layerPixelCount;
947 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700948 }
949 }
950
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 // No overlap layers
952 if (!numPTORLayersFound)
953 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700954
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700955 // Store the displayFrame and the sourceCrops of the layers
956 hwc_rect_t displayFrame[numAppLayers];
957 hwc_rect_t sourceCrop[numAppLayers];
958 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959 hwc_layer_1_t* layer = &list->hwLayers[i];
960 displayFrame[i] = layer->displayFrame;
961 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700962 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700963
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530964 /**
965 * It's possible that 2 PTOR layers might have overlapping.
966 * In such case, remove the intersection(again if peripheral)
967 * from the lower PTOR layer to avoid overlapping.
968 * If intersection is not on peripheral then compromise
969 * by reducing number of PTOR layers.
970 **/
971 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
972 if(isValidRect(commonRect)) {
973 overlapRect[1] = deductRect(overlapRect[1], commonRect);
974 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
975 }
976
977 ctx->mPtorInfo.count = numPTORLayersFound;
978 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
979 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
980 }
981
982 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
983 // reset PTOR
984 ctx->mPtorInfo.count = 0;
985 if(isValidRect(commonRect)) {
986 // If PTORs are intersecting restore displayframe of PTOR[1]
987 // before returning, as we have modified it above.
988 list->hwLayers[minLayerIndex[1]].displayFrame =
989 displayFrame[minLayerIndex[1]];
990 }
991 return false;
992 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700993 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
994 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
995
Xu Yangcda012c2014-07-30 21:57:21 +0800996 // Store the blending mode, planeAlpha, and transform of PTOR layers
997 int32_t blending[numPTORLayersFound];
998 uint8_t planeAlpha[numPTORLayersFound];
999 uint32_t transform[numPTORLayersFound];
1000
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001001 for(int j = 0; j < numPTORLayersFound; j++) {
1002 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001003
1004 // Update src crop of PTOR layer
1005 hwc_layer_1_t* layer = &list->hwLayers[index];
1006 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1007 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1008 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1009 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1010
1011 // Store & update w, h, format of PTOR layer
1012 private_handle_t *hnd = (private_handle_t *)layer->handle;
1013 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1014 layerWhf[j] = whf;
1015 hnd->width = renderBuf->width;
1016 hnd->height = renderBuf->height;
1017 hnd->format = renderBuf->format;
1018
Xu Yangcda012c2014-07-30 21:57:21 +08001019 // Store & update blending mode, planeAlpha and transform of PTOR layer
1020 blending[j] = layer->blending;
1021 planeAlpha[j] = layer->planeAlpha;
1022 transform[j] = layer->transform;
1023 layer->blending = HWC_BLENDING_NONE;
1024 layer->planeAlpha = 0xFF;
1025 layer->transform = 0;
1026
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001027 // Remove overlap from crop & displayFrame of below layers
1028 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001029 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001030 if(!isValidRect(getIntersection(layer->displayFrame,
1031 overlapRect[j]))) {
1032 continue;
1033 }
1034 // Update layer attributes
1035 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1036 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301037 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001038 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1039 layer->transform);
1040 layer->sourceCropf.left = (float)srcCrop.left;
1041 layer->sourceCropf.top = (float)srcCrop.top;
1042 layer->sourceCropf.right = (float)srcCrop.right;
1043 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1044 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001045 }
1046
1047 mCurrentFrame.mdpCount = numAppLayers;
1048 mCurrentFrame.fbCount = 0;
1049 mCurrentFrame.fbZ = -1;
1050
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301051 for (int j = 0; j < numAppLayers; j++) {
1052 if(isValidRect(list->hwLayers[j].displayFrame)) {
1053 mCurrentFrame.isFBComposed[j] = false;
1054 } else {
1055 mCurrentFrame.mdpCount--;
1056 mCurrentFrame.drop[j] = true;
1057 }
1058 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001059
1060 bool result = postHeuristicsHandling(ctx, list);
1061
1062 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001063 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001064 hwc_layer_1_t* layer = &list->hwLayers[i];
1065 layer->displayFrame = displayFrame[i];
1066 layer->sourceCropf.left = (float)sourceCrop[i].left;
1067 layer->sourceCropf.top = (float)sourceCrop[i].top;
1068 layer->sourceCropf.right = (float)sourceCrop[i].right;
1069 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1070 }
1071
Xu Yangcda012c2014-07-30 21:57:21 +08001072 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001073 for (int i = 0; i < numPTORLayersFound; i++) {
1074 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001075 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001076 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1077 hnd->width = layerWhf[i].w;
1078 hnd->height = layerWhf[i].h;
1079 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001080 layer->blending = blending[i];
1081 layer->planeAlpha = planeAlpha[i];
1082 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001083 }
1084
Sushil Chauhandefd3522014-05-13 18:17:12 -07001085 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001086 // reset PTOR
1087 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001088 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001089 } else {
1090 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1091 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001092 }
1093
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001094 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1095 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001096 return result;
1097}
1098
Saurabh Shahaa236822013-04-24 18:07:26 -07001099bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1100{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001101 if(!sEnableMixedMode) {
1102 //Mixed mode is disabled. No need to even try caching.
1103 return false;
1104 }
1105
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001106 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001107 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001108 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001109 cacheBasedComp(ctx, list);
1110 } else {
1111 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001112 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001113 }
1114
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001115 return ret;
1116}
1117
1118bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1119 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001120 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1121 return false;
1122
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001123 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001124 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001125 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001126
1127 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1128 for(int i = 0; i < numAppLayers; i++) {
1129 if(!mCurrentFrame.isFBComposed[i]) {
1130 hwc_layer_1_t* layer = &list->hwLayers[i];
1131 if(not isSupportedForMDPComp(ctx, layer)) {
1132 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1133 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001134 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001135 return false;
1136 }
1137 }
1138 }
1139
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001140 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001141 /* mark secure RGB layers for MDP comp */
1142 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301143 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001144 if(!ret) {
1145 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001146 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001147 return false;
1148 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001149
1150 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001151
Raj Kamal389d6e32014-08-04 14:43:24 +05301152 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001153 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301154 }
1155
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001156 if(!postHeuristicsHandling(ctx, list)) {
1157 ALOGD_IF(isDebug(), "post heuristic handling failed");
1158 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001159 return false;
1160 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001161 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1162 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001163
Saurabh Shahaa236822013-04-24 18:07:26 -07001164 return true;
1165}
1166
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001167bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001168 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001169 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1170 return false;
1171
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001172 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001173 return false;
1174 }
1175
Saurabh Shahb772ae32013-11-18 15:40:02 -08001176 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001177 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1178 const int stagesForMDP = min(sMaxPipesPerMixer,
1179 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001180
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001181 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1182 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1183 int lastMDPSupportedIndex = numAppLayers;
1184 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001185
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001186 //Find the minimum MDP batch size
1187 for(int i = 0; i < numAppLayers;i++) {
1188 if(mCurrentFrame.drop[i]) {
1189 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001190 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001191 }
1192 hwc_layer_1_t* layer = &list->hwLayers[i];
1193 if(not isSupportedForMDPComp(ctx, layer)) {
1194 lastMDPSupportedIndex = i;
1195 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1196 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001197 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001198 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001199 }
1200
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001201 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1202 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1203 mCurrentFrame.dropCount);
1204
1205 //Start at a point where the fb batch should at least have 2 layers, for
1206 //this mode to be justified.
1207 while(fbBatchSize < 2) {
1208 ++fbBatchSize;
1209 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001210 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001211
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001212 //If there are no layers for MDP, this mode doesnt make sense.
1213 if(mdpBatchSize < 1) {
1214 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1215 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001216 return false;
1217 }
1218
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001219 mCurrentFrame.reset(numAppLayers);
1220
1221 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1222 while(mdpBatchSize > 0) {
1223 //Mark layers for MDP comp
1224 int mdpBatchLeft = mdpBatchSize;
1225 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1226 if(mCurrentFrame.drop[i]) {
1227 continue;
1228 }
1229 mCurrentFrame.isFBComposed[i] = false;
1230 --mdpBatchLeft;
1231 }
1232
1233 mCurrentFrame.fbZ = mdpBatchSize;
1234 mCurrentFrame.fbCount = fbBatchSize;
1235 mCurrentFrame.mdpCount = mdpBatchSize;
1236
1237 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1238 __FUNCTION__, mdpBatchSize, fbBatchSize,
1239 mCurrentFrame.dropCount);
1240
1241 if(postHeuristicsHandling(ctx, list)) {
1242 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001243 __FUNCTION__);
1244 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1245 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001246 return true;
1247 }
1248
1249 reset(ctx);
1250 --mdpBatchSize;
1251 ++fbBatchSize;
1252 }
1253
1254 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001255}
1256
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001257bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301258 if(mDpy or isSecurePresent(ctx, mDpy) or
1259 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001260 return false;
1261 }
1262 return true;
1263}
1264
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001265bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1266 hwc_display_contents_1_t* list){
1267 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1268 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001269 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001270 return false;
1271 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001272 if(ctx->listStats[mDpy].secureUI)
1273 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001274 return true;
1275}
1276
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001277bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1278 hwc_display_contents_1_t* list) {
1279 const bool secureOnly = true;
1280 return videoOnlyComp(ctx, list, not secureOnly) or
1281 videoOnlyComp(ctx, list, secureOnly);
1282}
1283
1284bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001285 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001286 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1287 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001288 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001289
Saurabh Shahaa236822013-04-24 18:07:26 -07001290 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001291 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001292 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001293 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001294
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001295 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1296 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001297 return false;
1298 }
1299
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001300 /* Bail out if we are processing only secured video layers
1301 * and we dont have any */
1302 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001303 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001304 return false;
1305 }
1306
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001307 if(mCurrentFrame.fbCount)
1308 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001309
Raj Kamal389d6e32014-08-04 14:43:24 +05301310 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001311 adjustForSourceSplit(ctx, list);
1312 }
1313
1314 if(!postHeuristicsHandling(ctx, list)) {
1315 ALOGD_IF(isDebug(), "post heuristic handling failed");
1316 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001317 return false;
1318 }
1319
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001320 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1321 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001322 return true;
1323}
1324
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001325/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1326bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1327 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001328 // Fall back to video only composition, if AIV video mode is enabled
1329 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001330 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1331 __FUNCTION__, mDpy);
1332 return false;
1333 }
1334
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001335 const bool secureOnly = true;
1336 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1337 mdpOnlyLayersComp(ctx, list, secureOnly);
1338
1339}
1340
1341bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1342 hwc_display_contents_1_t* list, bool secureOnly) {
1343
1344 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1345 return false;
1346
1347 /* Bail out if we are processing only secured video layers
1348 * and we dont have any */
1349 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1350 reset(ctx);
1351 return false;
1352 }
1353
1354 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1355 mCurrentFrame.reset(numAppLayers);
1356 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1357
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001358 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001359 /* mark secure RGB layers for MDP comp */
1360 updateSecureRGB(ctx, list);
1361
1362 if(mCurrentFrame.mdpCount == 0) {
1363 reset(ctx);
1364 return false;
1365 }
1366
1367 /* find the maximum batch of layers to be marked for framebuffer */
1368 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1369 if(!ret) {
1370 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1371 reset(ctx);
1372 return false;
1373 }
1374
1375 if(sEnableYUVsplit){
1376 adjustForSourceSplit(ctx, list);
1377 }
1378
1379 if(!postHeuristicsHandling(ctx, list)) {
1380 ALOGD_IF(isDebug(), "post heuristic handling failed");
1381 reset(ctx);
1382 return false;
1383 }
1384
1385 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1386 __FUNCTION__);
1387 return true;
1388}
1389
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001390/* Checks for conditions where YUV layers cannot be bypassed */
1391bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001392 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001393 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001394 return false;
1395 }
1396
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001397 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001398 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1399 return false;
1400 }
1401
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001402 if(isSecuring(ctx, layer)) {
1403 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1404 return false;
1405 }
1406
Saurabh Shah4fdde762013-04-30 18:47:33 -07001407 if(!isValidDimension(ctx, layer)) {
1408 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1409 __FUNCTION__);
1410 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001411 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001412
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001413 if(layer->planeAlpha < 0xFF) {
1414 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1415 in video only mode",
1416 __FUNCTION__);
1417 return false;
1418 }
1419
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001420 return true;
1421}
1422
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001423/* Checks for conditions where Secure RGB layers cannot be bypassed */
1424bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1425 if(isSkipLayer(layer)) {
1426 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1427 __FUNCTION__, mDpy);
1428 return false;
1429 }
1430
1431 if(isSecuring(ctx, layer)) {
1432 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1433 return false;
1434 }
1435
1436 if(not isSupportedForMDPComp(ctx, layer)) {
1437 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1438 __FUNCTION__);
1439 return false;
1440 }
1441 return true;
1442}
1443
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301444/* starts at fromIndex and check for each layer to find
1445 * if it it has overlapping with any Updating layer above it in zorder
1446 * till the end of the batch. returns true if it finds any intersection */
1447bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1448 int fromIndex, int toIndex) {
1449 for(int i = fromIndex; i < toIndex; i++) {
1450 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1451 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1452 return false;
1453 }
1454 }
1455 }
1456 return true;
1457}
1458
1459/* Checks if given layer at targetLayerIndex has any
1460 * intersection with all the updating layers in beween
1461 * fromIndex and toIndex. Returns true if it finds intersectiion */
1462bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1463 int fromIndex, int toIndex, int targetLayerIndex) {
1464 for(int i = fromIndex; i <= toIndex; i++) {
1465 if(!mCurrentFrame.isFBComposed[i]) {
1466 if(areLayersIntersecting(&list->hwLayers[i],
1467 &list->hwLayers[targetLayerIndex])) {
1468 return true;
1469 }
1470 }
1471 }
1472 return false;
1473}
1474
1475int MDPComp::getBatch(hwc_display_contents_1_t* list,
1476 int& maxBatchStart, int& maxBatchEnd,
1477 int& maxBatchCount) {
1478 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301479 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001480 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301481 while (i < mCurrentFrame.layerCount) {
1482 int batchCount = 0;
1483 int batchStart = i;
1484 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001485 /* Adjust batch Z order with the dropped layers so far */
1486 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301487 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301488 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301489 while(i < mCurrentFrame.layerCount) {
1490 if(!mCurrentFrame.isFBComposed[i]) {
1491 if(!batchCount) {
1492 i++;
1493 break;
1494 }
1495 updatingLayersAbove++;
1496 i++;
1497 continue;
1498 } else {
1499 if(mCurrentFrame.drop[i]) {
1500 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001501 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301502 continue;
1503 } else if(updatingLayersAbove <= 0) {
1504 batchCount++;
1505 batchEnd = i;
1506 i++;
1507 continue;
1508 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1509
1510 // We have a valid updating layer already. If layer-i not
1511 // have overlapping with all updating layers in between
1512 // batch-start and i, then we can add layer i to batch.
1513 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1514 batchCount++;
1515 batchEnd = i;
1516 i++;
1517 continue;
1518 } else if(canPushBatchToTop(list, batchStart, i)) {
1519 //If All the non-updating layers with in this batch
1520 //does not have intersection with the updating layers
1521 //above in z-order, then we can safely move the batch to
1522 //higher z-order. Increment fbZ as it is moving up.
1523 if( firstZReverseIndex < 0) {
1524 firstZReverseIndex = i;
1525 }
1526 batchCount++;
1527 batchEnd = i;
1528 fbZ += updatingLayersAbove;
1529 i++;
1530 updatingLayersAbove = 0;
1531 continue;
1532 } else {
1533 //both failed.start the loop again from here.
1534 if(firstZReverseIndex >= 0) {
1535 i = firstZReverseIndex;
1536 }
1537 break;
1538 }
1539 }
1540 }
1541 }
1542 if(batchCount > maxBatchCount) {
1543 maxBatchCount = batchCount;
1544 maxBatchStart = batchStart;
1545 maxBatchEnd = batchEnd;
1546 fbZOrder = fbZ;
1547 }
1548 }
1549 return fbZOrder;
1550}
1551
1552bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1553 hwc_display_contents_1_t* list) {
1554 /* Idea is to keep as many non-updating(cached) layers in FB and
1555 * send rest of them through MDP. This is done in 2 steps.
1556 * 1. Find the maximum contiguous batch of non-updating layers.
1557 * 2. See if we can improve this batch size for caching by adding
1558 * opaque layers around the batch, if they don't have
1559 * any overlapping with the updating layers in between.
1560 * NEVER mark an updating layer for caching.
1561 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001562
1563 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001564 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301566 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001567
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001568 /* Nothing is cached. No batching needed */
1569 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001570 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001571 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001572
1573 /* No MDP comp layers, try to use other comp modes */
1574 if(mCurrentFrame.mdpCount == 0) {
1575 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001576 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301578 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001579
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001581 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001582 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001583 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301584 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001585 if(!mCurrentFrame.drop[i]){
1586 //If an unsupported layer is being attempted to
1587 //be pulled out we should fail
1588 if(not isSupportedForMDPComp(ctx, layer)) {
1589 return false;
1590 }
1591 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001592 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001593 }
1594 }
1595
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301596 // update the frame data
1597 mCurrentFrame.fbZ = fbZ;
1598 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001599 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001600 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001601
1602 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301603 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001604
1605 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001607
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001609 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001611 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001613 for(int i = 0; i < numAppLayers; i++) {
1614 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001615 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001616 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001617 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001619 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001620 }
1621 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001622
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001623 frame.fbCount = fbCount;
1624 frame.mdpCount = frame.layerCount - frame.fbCount
1625 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001626
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001627 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1628 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001629}
1630
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001631// drop other non-AIV layers from external display list.
1632void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001633 hwc_display_contents_1_t* list) {
1634 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1635 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001636 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001637 mCurrentFrame.dropCount++;
1638 mCurrentFrame.drop[i] = true;
1639 }
1640 }
1641 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1642 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1643 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1644 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1645 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1646 mCurrentFrame.dropCount);
1647}
1648
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001649void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001650 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001651 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1652 for(int index = 0;index < nYuvCount; index++){
1653 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1654 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1655
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001656 if(mCurrentFrame.drop[nYuvIndex]) {
1657 continue;
1658 }
1659
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001661 if(!frame.isFBComposed[nYuvIndex]) {
1662 frame.isFBComposed[nYuvIndex] = true;
1663 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664 }
1665 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001666 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001667 private_handle_t *hnd = (private_handle_t *)layer->handle;
1668 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001669 frame.isFBComposed[nYuvIndex] = false;
1670 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001671 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672 }
1673 }
1674 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001675
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001676 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1677 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678}
1679
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001680void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1681 hwc_display_contents_1_t* list) {
1682 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1683 for(int index = 0;index < nSecureRGBCount; index++){
1684 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1685 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1686
1687 if(!isSecureRGBDoable(ctx, layer)) {
1688 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1689 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1690 mCurrentFrame.fbCount++;
1691 }
1692 } else {
1693 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1694 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1695 mCurrentFrame.fbCount--;
1696 }
1697 }
1698 }
1699
1700 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1701 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1702 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1703 mCurrentFrame.fbCount);
1704}
1705
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001706hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1707 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001708 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001709
1710 /* Update only the region of FB needed for composition */
1711 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1712 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1713 hwc_layer_1_t* layer = &list->hwLayers[i];
1714 hwc_rect_t dst = layer->displayFrame;
1715 fbRect = getUnion(fbRect, dst);
1716 }
1717 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001718 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001719 return fbRect;
1720}
1721
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001722bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1723 hwc_display_contents_1_t* list) {
1724
1725 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001726 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001727 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1728 return false;
1729 }
1730
1731 //Limitations checks
1732 if(!hwLimitationsCheck(ctx, list)) {
1733 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1734 return false;
1735 }
1736
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001737 //Configure framebuffer first if applicable
1738 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001739 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001740 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1741 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001742 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1743 __FUNCTION__);
1744 return false;
1745 }
1746 }
1747
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001748 mCurrentFrame.map();
1749
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001750 if(!allocLayerPipes(ctx, list)) {
1751 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001752 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001753 }
1754
1755 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001756 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001757 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001758 int mdpIndex = mCurrentFrame.layerToMDP[index];
1759 hwc_layer_1_t* layer = &list->hwLayers[index];
1760
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301761 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1762 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1763 mdpNextZOrder++;
1764 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001765 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1766 cur_pipe->zOrder = mdpNextZOrder++;
1767
radhakrishnac9a67412013-09-25 17:40:42 +05301768 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301769 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301770 if(configure4k2kYuv(ctx, layer,
1771 mCurrentFrame.mdpToLayer[mdpIndex])
1772 != 0 ){
1773 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1774 for layer %d",__FUNCTION__, index);
1775 return false;
1776 }
1777 else{
1778 mdpNextZOrder++;
1779 }
1780 continue;
1781 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001782 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1783 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301784 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001785 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001786 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001787 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788 }
1789
Saurabh Shaha36be922013-12-16 18:18:39 -08001790 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1791 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1792 ,__FUNCTION__, mDpy);
1793 return false;
1794 }
1795
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001796 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001797 return true;
1798}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001799
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001800bool MDPComp::resourceCheck(hwc_context_t* ctx,
1801 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001802 const bool fbUsed = mCurrentFrame.fbCount;
1803 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1804 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1805 return false;
1806 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001807
1808 //Will benefit cases where a video has non-updating background.
1809 if((mDpy > HWC_DISPLAY_PRIMARY) and
1810 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1811 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1812 return false;
1813 }
1814
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001815 // Init rotCount to number of rotate sessions used by other displays
1816 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1817 // Count the number of rotator sessions required for current display
1818 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1819 if(!mCurrentFrame.isFBComposed[index]) {
1820 hwc_layer_1_t* layer = &list->hwLayers[index];
1821 private_handle_t *hnd = (private_handle_t *)layer->handle;
1822 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1823 rotCount++;
1824 }
1825 }
1826 }
1827 // if number of layers to rotate exceeds max rotator sessions, bail out.
1828 if(rotCount > RotMgr::MAX_ROT_SESS) {
1829 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1830 __FUNCTION__, mDpy);
1831 return false;
1832 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001833 return true;
1834}
1835
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301836bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1837 hwc_display_contents_1_t* list) {
1838
1839 //A-family hw limitation:
1840 //If a layer need alpha scaling, MDP can not support.
1841 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1842 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1843 if(!mCurrentFrame.isFBComposed[i] &&
1844 isAlphaScaled( &list->hwLayers[i])) {
1845 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1846 return false;
1847 }
1848 }
1849 }
1850
1851 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1852 //If multiple layers requires downscaling and also they are overlapping
1853 //fall back to GPU since MDSS can not handle it.
1854 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1855 qdutils::MDPVersion::getInstance().is8x26()) {
1856 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1857 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1858 if(!mCurrentFrame.isFBComposed[i] &&
1859 isDownscaleRequired(botLayer)) {
1860 //if layer-i is marked for MDP and needs downscaling
1861 //check if any MDP layer on top of i & overlaps with layer-i
1862 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1863 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1864 if(!mCurrentFrame.isFBComposed[j] &&
1865 isDownscaleRequired(topLayer)) {
1866 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1867 topLayer->displayFrame);
1868 if(isValidRect(r))
1869 return false;
1870 }
1871 }
1872 }
1873 }
1874 }
1875 return true;
1876}
1877
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301878void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1879 //For primary display, set the dynamic refreshrate
1880 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1881 ctx->mUseMetaDataRefreshRate) {
1882 FrameInfo frame;
1883 frame.reset(mCurrentFrame.layerCount);
1884 memset(&frame.drop, 0, sizeof(frame.drop));
1885 frame.dropCount = 0;
1886 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1887 __FUNCTION__);
1888 updateLayerCache(ctx, list, frame);
1889 updateYUV(ctx, list, false /*secure only*/, frame);
1890 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1891 MDPVersion& mdpHw = MDPVersion::getInstance();
1892 if(sIdleFallBack) {
1893 //Set minimum panel refresh rate during idle timeout
1894 refreshRate = mdpHw.getMinFpsSupported();
1895 } else if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1896 (frame.layerCount == 1)) {
1897 //Set the new fresh rate, if there is only one updating YUV layer
1898 //or there is one single RGB layer with this request
1899 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1900 }
1901 setRefreshRate(ctx, mDpy, refreshRate);
1902 }
1903}
1904
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001905int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001906 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001907 char property[PROPERTY_VALUE_MAX];
1908
Raj Kamal4393eaa2014-06-06 13:45:20 +05301909 if(!ctx || !list) {
1910 ALOGE("%s: Invalid context or list",__FUNCTION__);
1911 mCachedFrame.reset();
1912 return -1;
1913 }
1914
1915 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001916 if(mDpy == HWC_DISPLAY_PRIMARY) {
1917 sSimulationFlags = 0;
1918 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1919 int currentFlags = atoi(property);
1920 if(currentFlags != sSimulationFlags) {
1921 sSimulationFlags = currentFlags;
1922 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1923 sSimulationFlags, sSimulationFlags);
1924 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001925 }
1926 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001927 // reset PTOR
1928 if(!mDpy)
1929 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001930
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301931 //reset old data
1932 mCurrentFrame.reset(numLayers);
1933 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1934 mCurrentFrame.dropCount = 0;
1935
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301936 //Do not cache the information for next draw cycle.
1937 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1938 ALOGI("%s: Unsupported layer count for mdp composition",
1939 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001940 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301941#ifdef DYNAMIC_FPS
1942 setDynRefreshRate(ctx, list);
1943#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001944 return -1;
1945 }
1946
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001947 // Detect the start of animation and fall back to GPU only once to cache
1948 // all the layers in FB and display FB content untill animation completes.
1949 if(ctx->listStats[mDpy].isDisplayAnimating) {
1950 mCurrentFrame.needsRedraw = false;
1951 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1952 mCurrentFrame.needsRedraw = true;
1953 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1954 }
1955 setMDPCompLayerFlags(ctx, list);
1956 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301957#ifdef DYNAMIC_FPS
1958 setDynRefreshRate(ctx, list);
1959#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001960 ret = -1;
1961 return ret;
1962 } else {
1963 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1964 }
1965
Saurabh Shahb39f8152013-08-22 10:21:44 -07001966 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001967 if(isFrameDoable(ctx)) {
1968 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001969 // if AIV Video mode is enabled, drop all non AIV layers from the
1970 // external display list.
1971 if(ctx->listStats[mDpy].mAIVVideoMode) {
1972 dropNonAIVLayers(ctx, list);
1973 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001974
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001975 // if tryFullFrame fails, try to push all video and secure RGB layers
1976 // to MDP for composition.
1977 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001978 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301979 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001980 setMDPCompLayerFlags(ctx, list);
1981 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001982 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001983 reset(ctx);
1984 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1985 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001986 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001987 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1988 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001989 }
1990 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301991 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1992 enablePartialUpdateForMDP3) {
1993 generateROI(ctx, list);
1994 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1995 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1996 }
1997 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001998 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1999 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002000 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002001 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002002
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002003 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002004 ALOGD("GEOMETRY change: %d",
2005 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002006 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002007 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002008 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002009 }
2010
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002011#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302012 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002013#endif
2014
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002015 mCachedFrame.cacheAll(list);
2016 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002017 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002018}
2019
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002020bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302021
2022 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302023 int mdpIndex = mCurrentFrame.layerToMDP[index];
2024 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2025 info.pipeInfo = new MdpYUVPipeInfo;
2026 info.rot = NULL;
2027 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302028
2029 pipe_info.lIndex = ovutils::OV_INVALID;
2030 pipe_info.rIndex = ovutils::OV_INVALID;
2031
Saurabh Shahc62f3982014-03-05 14:28:26 -08002032 Overlay::PipeSpecs pipeSpecs;
2033 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2034 pipeSpecs.needsScaling = true;
2035 pipeSpecs.dpy = mDpy;
2036 pipeSpecs.fb = false;
2037
2038 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302039 if(pipe_info.lIndex == ovutils::OV_INVALID){
2040 bRet = false;
2041 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2042 __FUNCTION__);
2043 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002044 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302045 if(pipe_info.rIndex == ovutils::OV_INVALID){
2046 bRet = false;
2047 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2048 __FUNCTION__);
2049 }
2050 return bRet;
2051}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002052
2053int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2054 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002055 if (ctx->mPtorInfo.isActive()) {
2056 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002057 if (fd < 0) {
2058 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002059 }
2060 }
2061 return fd;
2062}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002063//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002064
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002065void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302066 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002067 //If 4k2k Yuv layer split is possible, and if
2068 //fbz is above 4k2k layer, increment fb zorder by 1
2069 //as we split 4k2k layer and increment zorder for right half
2070 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002071 if(!ctx)
2072 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002073 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302074 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2075 index++) {
2076 if(!mCurrentFrame.isFBComposed[index]) {
2077 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2078 mdpNextZOrder++;
2079 }
2080 mdpNextZOrder++;
2081 hwc_layer_1_t* layer = &list->hwLayers[index];
2082 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302083 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302084 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2085 mCurrentFrame.fbZ += 1;
2086 mdpNextZOrder++;
2087 //As we split 4kx2k yuv layer and program to 2 VG pipes
2088 //(if available) increase mdpcount by 1.
2089 mCurrentFrame.mdpCount++;
2090 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002091 }
2092 }
2093 }
radhakrishnac9a67412013-09-25 17:40:42 +05302094}
2095
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002096/*
2097 * Configures pipe(s) for MDP composition
2098 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002099int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002100 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002101 MdpPipeInfoNonSplit& mdp_info =
2102 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302103 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002104 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002105 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002106
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002107 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2108 __FUNCTION__, layer, zOrder, dest);
2109
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002110 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002111 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002112}
2113
Saurabh Shah88e4d272013-09-03 13:31:29 -07002114bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002115 hwc_display_contents_1_t* list) {
2116 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002117
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002118 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002119
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002120 hwc_layer_1_t* layer = &list->hwLayers[index];
2121 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302122 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002123 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302124 continue;
2125 }
2126 }
2127
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002128 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002129 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002130 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002131 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002132 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002133
Saurabh Shahc62f3982014-03-05 14:28:26 -08002134 Overlay::PipeSpecs pipeSpecs;
2135 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2136 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2137 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2138 (qdutils::MDPVersion::getInstance().is8x26() and
2139 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2140 pipeSpecs.dpy = mDpy;
2141 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002142 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002143
Saurabh Shahc62f3982014-03-05 14:28:26 -08002144 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2145
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002146 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002147 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002148 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002149 }
2150 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002151 return true;
2152}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002153
radhakrishnac9a67412013-09-25 17:40:42 +05302154int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2155 PipeLayerPair& PipeLayerPair) {
2156 MdpYUVPipeInfo& mdp_info =
2157 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2158 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302159 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302160 eDest lDest = mdp_info.lIndex;
2161 eDest rDest = mdp_info.rIndex;
2162
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002163 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302164 lDest, rDest, &PipeLayerPair.rot);
2165}
2166
Saurabh Shah88e4d272013-09-03 13:31:29 -07002167bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002168
Raj Kamal4393eaa2014-06-06 13:45:20 +05302169 if(!isEnabled() or !mModeOn) {
2170 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302171 return true;
2172 }
2173
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002174 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002175 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002176 sHandleTimeout = true;
2177 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002178
2179 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002180 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002181
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002182 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2183 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002184 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002185 if(mCurrentFrame.isFBComposed[i]) continue;
2186
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002187 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002188 private_handle_t *hnd = (private_handle_t *)layer->handle;
2189 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002190 if (!(layer->flags & HWC_COLOR_FILL)) {
2191 ALOGE("%s handle null", __FUNCTION__);
2192 return false;
2193 }
2194 // No PLAY for Color layer
2195 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2196 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002197 }
2198
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002199 int mdpIndex = mCurrentFrame.layerToMDP[i];
2200
Raj Kamal389d6e32014-08-04 14:43:24 +05302201 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302202 {
2203 MdpYUVPipeInfo& pipe_info =
2204 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2205 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2206 ovutils::eDest indexL = pipe_info.lIndex;
2207 ovutils::eDest indexR = pipe_info.rIndex;
2208 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302209 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302210 if(rot) {
2211 rot->queueBuffer(fd, offset);
2212 fd = rot->getDstMemId();
2213 offset = rot->getDstOffset();
2214 }
2215 if(indexL != ovutils::OV_INVALID) {
2216 ovutils::eDest destL = (ovutils::eDest)indexL;
2217 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2218 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2219 if (!ov.queueBuffer(fd, offset, destL)) {
2220 ALOGE("%s: queueBuffer failed for display:%d",
2221 __FUNCTION__, mDpy);
2222 return false;
2223 }
2224 }
2225
2226 if(indexR != ovutils::OV_INVALID) {
2227 ovutils::eDest destR = (ovutils::eDest)indexR;
2228 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2229 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2230 if (!ov.queueBuffer(fd, offset, destR)) {
2231 ALOGE("%s: queueBuffer failed for display:%d",
2232 __FUNCTION__, mDpy);
2233 return false;
2234 }
2235 }
2236 }
2237 else{
2238 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002239 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302240 ovutils::eDest dest = pipe_info.index;
2241 if(dest == ovutils::OV_INVALID) {
2242 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002243 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302244 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002245
radhakrishnac9a67412013-09-25 17:40:42 +05302246 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2247 continue;
2248 }
2249
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002250 int fd = hnd->fd;
2251 uint32_t offset = (uint32_t)hnd->offset;
2252 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2253 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002254 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002255 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002256 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002257 }
2258
radhakrishnac9a67412013-09-25 17:40:42 +05302259 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2260 using pipe: %d", __FUNCTION__, layer,
2261 hnd, dest );
2262
radhakrishnac9a67412013-09-25 17:40:42 +05302263 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2264 if(rot) {
2265 if(!rot->queueBuffer(fd, offset))
2266 return false;
2267 fd = rot->getDstMemId();
2268 offset = rot->getDstOffset();
2269 }
2270
2271 if (!ov.queueBuffer(fd, offset, dest)) {
2272 ALOGE("%s: queueBuffer failed for display:%d ",
2273 __FUNCTION__, mDpy);
2274 return false;
2275 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002276 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002277
2278 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002279 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002280 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002281}
2282
Saurabh Shah88e4d272013-09-03 13:31:29 -07002283//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002284
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002285void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302286 hwc_display_contents_1_t* list){
2287 //if 4kx2k yuv layer is totally present in either in left half
2288 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302289 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302290 if(mCurrentFrame.fbZ >= 0) {
2291 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2292 index++) {
2293 if(!mCurrentFrame.isFBComposed[index]) {
2294 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2295 mdpNextZOrder++;
2296 }
2297 mdpNextZOrder++;
2298 hwc_layer_1_t* layer = &list->hwLayers[index];
2299 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302300 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302301 hwc_rect_t dst = layer->displayFrame;
2302 if((dst.left > lSplit) || (dst.right < lSplit)) {
2303 mCurrentFrame.mdpCount += 1;
2304 }
2305 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2306 mCurrentFrame.fbZ += 1;
2307 mdpNextZOrder++;
2308 }
2309 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002310 }
radhakrishnac9a67412013-09-25 17:40:42 +05302311 }
2312}
2313
Saurabh Shah88e4d272013-09-03 13:31:29 -07002314bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002315 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002316
Saurabh Shahc62f3982014-03-05 14:28:26 -08002317 const int lSplit = getLeftSplit(ctx, mDpy);
2318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002319 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002320 pipe_info.lIndex = ovutils::OV_INVALID;
2321 pipe_info.rIndex = ovutils::OV_INVALID;
2322
Saurabh Shahc62f3982014-03-05 14:28:26 -08002323 Overlay::PipeSpecs pipeSpecs;
2324 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2325 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2326 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2327 pipeSpecs.dpy = mDpy;
2328 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2329 pipeSpecs.fb = false;
2330
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002331 // Acquire pipe only for the updating half
2332 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2333 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2334
2335 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002336 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002337 if(pipe_info.lIndex == ovutils::OV_INVALID)
2338 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002339 }
2340
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002341 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002342 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2343 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002344 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002345 return false;
2346 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002347
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002348 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002349}
2350
Saurabh Shah88e4d272013-09-03 13:31:29 -07002351bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002352 hwc_display_contents_1_t* list) {
2353 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002354
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002355 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002356
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002357 hwc_layer_1_t* layer = &list->hwLayers[index];
2358 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302359 hwc_rect_t dst = layer->displayFrame;
2360 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302361 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302362 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002363 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302364 continue;
2365 }
2366 }
2367 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002368 int mdpIndex = mCurrentFrame.layerToMDP[index];
2369 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002370 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002371 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002372 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002373
Saurabh Shahc62f3982014-03-05 14:28:26 -08002374 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2375 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2376 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002377 return false;
2378 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002379 }
2380 return true;
2381}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002382
radhakrishnac9a67412013-09-25 17:40:42 +05302383int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2384 PipeLayerPair& PipeLayerPair) {
2385 const int lSplit = getLeftSplit(ctx, mDpy);
2386 hwc_rect_t dst = layer->displayFrame;
2387 if((dst.left > lSplit)||(dst.right < lSplit)){
2388 MdpYUVPipeInfo& mdp_info =
2389 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2390 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302391 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302392 eDest lDest = mdp_info.lIndex;
2393 eDest rDest = mdp_info.rIndex;
2394
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002395 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302396 lDest, rDest, &PipeLayerPair.rot);
2397 }
2398 else{
2399 return configure(ctx, layer, PipeLayerPair);
2400 }
2401}
2402
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403/*
2404 * Configures pipe(s) for MDP composition
2405 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002406int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002407 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002408 MdpPipeInfoSplit& mdp_info =
2409 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002410 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302411 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002412 eDest lDest = mdp_info.lIndex;
2413 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002414
2415 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2416 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2417
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002418 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002419 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002420}
2421
Saurabh Shah88e4d272013-09-03 13:31:29 -07002422bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002423
Raj Kamal4393eaa2014-06-06 13:45:20 +05302424 if(!isEnabled() or !mModeOn) {
2425 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302426 return true;
2427 }
2428
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002429 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002430 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002431 sHandleTimeout = true;
2432 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002433
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002434 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002435 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002436
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002437 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2438 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002439 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002440 if(mCurrentFrame.isFBComposed[i]) continue;
2441
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002442 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002443 private_handle_t *hnd = (private_handle_t *)layer->handle;
2444 if(!hnd) {
2445 ALOGE("%s handle null", __FUNCTION__);
2446 return false;
2447 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002448
2449 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2450 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002451 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002452
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002453 int mdpIndex = mCurrentFrame.layerToMDP[i];
2454
Raj Kamal389d6e32014-08-04 14:43:24 +05302455 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302456 {
2457 MdpYUVPipeInfo& pipe_info =
2458 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2459 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2460 ovutils::eDest indexL = pipe_info.lIndex;
2461 ovutils::eDest indexR = pipe_info.rIndex;
2462 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302463 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302464 if(rot) {
2465 rot->queueBuffer(fd, offset);
2466 fd = rot->getDstMemId();
2467 offset = rot->getDstOffset();
2468 }
2469 if(indexL != ovutils::OV_INVALID) {
2470 ovutils::eDest destL = (ovutils::eDest)indexL;
2471 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2472 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2473 if (!ov.queueBuffer(fd, offset, destL)) {
2474 ALOGE("%s: queueBuffer failed for display:%d",
2475 __FUNCTION__, mDpy);
2476 return false;
2477 }
2478 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002479
radhakrishnac9a67412013-09-25 17:40:42 +05302480 if(indexR != ovutils::OV_INVALID) {
2481 ovutils::eDest destR = (ovutils::eDest)indexR;
2482 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2483 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2484 if (!ov.queueBuffer(fd, offset, destR)) {
2485 ALOGE("%s: queueBuffer failed for display:%d",
2486 __FUNCTION__, mDpy);
2487 return false;
2488 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002489 }
2490 }
radhakrishnac9a67412013-09-25 17:40:42 +05302491 else{
2492 MdpPipeInfoSplit& pipe_info =
2493 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2494 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002495
radhakrishnac9a67412013-09-25 17:40:42 +05302496 ovutils::eDest indexL = pipe_info.lIndex;
2497 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002498
radhakrishnac9a67412013-09-25 17:40:42 +05302499 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002500 uint32_t offset = (uint32_t)hnd->offset;
2501 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2502 if (!mDpy && (index != -1)) {
2503 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2504 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002505 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002506 }
radhakrishnac9a67412013-09-25 17:40:42 +05302507
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002508 if(ctx->mAD->draw(ctx, fd, offset)) {
2509 fd = ctx->mAD->getDstFd();
2510 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002511 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002512
radhakrishnac9a67412013-09-25 17:40:42 +05302513 if(rot) {
2514 rot->queueBuffer(fd, offset);
2515 fd = rot->getDstMemId();
2516 offset = rot->getDstOffset();
2517 }
2518
2519 //************* play left mixer **********
2520 if(indexL != ovutils::OV_INVALID) {
2521 ovutils::eDest destL = (ovutils::eDest)indexL;
2522 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2523 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2524 if (!ov.queueBuffer(fd, offset, destL)) {
2525 ALOGE("%s: queueBuffer failed for left mixer",
2526 __FUNCTION__);
2527 return false;
2528 }
2529 }
2530
2531 //************* play right mixer **********
2532 if(indexR != ovutils::OV_INVALID) {
2533 ovutils::eDest destR = (ovutils::eDest)indexR;
2534 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2535 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2536 if (!ov.queueBuffer(fd, offset, destR)) {
2537 ALOGE("%s: queueBuffer failed for right mixer",
2538 __FUNCTION__);
2539 return false;
2540 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002541 }
2542 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002543
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002544 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2545 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002546
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002547 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002548}
Saurabh Shahab47c692014-02-12 18:45:57 -08002549
2550//================MDPCompSrcSplit==============================================
2551bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002552 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002553 private_handle_t *hnd = (private_handle_t *)layer->handle;
2554 hwc_rect_t dst = layer->displayFrame;
2555 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2556 pipe_info.lIndex = ovutils::OV_INVALID;
2557 pipe_info.rIndex = ovutils::OV_INVALID;
2558
2559 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2560 //should have a higher priority than the right one. Pipe priorities are
2561 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002562
Saurabh Shahc62f3982014-03-05 14:28:26 -08002563 Overlay::PipeSpecs pipeSpecs;
2564 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2565 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2566 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2567 pipeSpecs.dpy = mDpy;
2568 pipeSpecs.fb = false;
2569
Saurabh Shahab47c692014-02-12 18:45:57 -08002570 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002571 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002572 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002573 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002574 }
2575
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002576 /* Use 2 pipes IF
2577 a) Layer's crop width is > 2048 or
2578 b) Layer's dest width > 2048 or
2579 c) On primary, driver has indicated with caps to split always. This is
2580 based on an empirically derived value of panel height. Applied only
2581 if the layer's width is > mixer's width
2582 */
2583
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302584 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002585 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302586 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002587 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2588 const uint32_t dstWidth = dst.right - dst.left;
2589 const uint32_t dstHeight = dst.bottom - dst.top;
2590 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002591 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002592 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2593 crop.bottom - crop.top;
2594 //Approximation to actual clock, ignoring the common factors in pipe and
2595 //mixer cases like line_time
2596 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2597 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002598
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002599 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2600 //pipe line length, we are still using 2 pipes. This is fine just because
2601 //this is source split where destination doesn't matter. Evaluate later to
2602 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002603 if(dstWidth > mdpHw.getMaxMixerWidth() or
2604 cropWidth > mdpHw.getMaxMixerWidth() or
2605 (primarySplitAlways and
2606 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002607 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002608 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002609 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002610 }
2611
2612 // Return values
2613 // 1 Left pipe is higher priority, do nothing.
2614 // 0 Pipes of same priority.
2615 //-1 Right pipe is of higher priority, needs swap.
2616 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2617 pipe_info.rIndex) == -1) {
2618 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002619 }
2620 }
2621
2622 return true;
2623}
2624
Saurabh Shahab47c692014-02-12 18:45:57 -08002625int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2626 PipeLayerPair& PipeLayerPair) {
2627 private_handle_t *hnd = (private_handle_t *)layer->handle;
2628 if(!hnd) {
2629 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2630 return -1;
2631 }
2632 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2633 MdpPipeInfoSplit& mdp_info =
2634 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2635 Rotator **rot = &PipeLayerPair.rot;
2636 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002637 eDest lDest = mdp_info.lIndex;
2638 eDest rDest = mdp_info.rIndex;
2639 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2640 hwc_rect_t dst = layer->displayFrame;
2641 int transform = layer->transform;
2642 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002643 int rotFlags = ROT_FLAGS_NONE;
2644 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2645 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2646
2647 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2648 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2649
2650 // Handle R/B swap
2651 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2652 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2653 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2654 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2655 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2656 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002657 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002658 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2659 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002660 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002661 /* Calculate the external display position based on MDP downscale,
2662 ActionSafe, and extorientation features. */
2663 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002664
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002665 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302666 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002667 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668
2669 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2670 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002671 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002672 }
2673
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002674 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002675 (*rot) = ctx->mRotMgr->getNext();
2676 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002677 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002678 //If the video is using a single pipe, enable BWC
2679 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002680 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2681 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002682 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002683 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002684 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002685 ALOGE("%s: configRotator failed!", __FUNCTION__);
2686 return -1;
2687 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002688 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002689 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002690 }
2691
2692 //If 2 pipes being used, divide layer into half, crop and dst
2693 hwc_rect_t cropL = crop;
2694 hwc_rect_t cropR = crop;
2695 hwc_rect_t dstL = dst;
2696 hwc_rect_t dstR = dst;
2697 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2698 cropL.right = (crop.right + crop.left) / 2;
2699 cropR.left = cropL.right;
2700 sanitizeSourceCrop(cropL, cropR, hnd);
2701
Saurabh Shahb729b192014-08-15 18:04:24 -07002702 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002703 //Swap crops on H flip since 2 pipes are being used
2704 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2705 hwc_rect_t tmp = cropL;
2706 cropL = cropR;
2707 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002708 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002709 }
2710
Saurabh Shahb729b192014-08-15 18:04:24 -07002711 //cropSwap trick: If the src and dst widths are both odd, let us say
2712 //2507, then splitting both into half would cause left width to be 1253
2713 //and right 1254. If crop is swapped because of H flip, this will cause
2714 //left crop width to be 1254, whereas left dst width remains 1253, thus
2715 //inducing a scaling that is unaccounted for. To overcome that we add 1
2716 //to the dst width if there is a cropSwap. So if the original width was
2717 //2507, the left dst width will be 1254. Even if the original width was
2718 //even for ex: 2508, the left dst width will still remain 1254.
2719 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002720 dstR.left = dstL.right;
2721 }
2722
2723 //For the mdp, since either we are pre-rotating or MDP does flips
2724 orient = OVERLAY_TRANSFORM_0;
2725 transform = 0;
2726
2727 //configure left pipe
2728 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002729 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002730 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2731 (ovutils::eBlending) getBlending(layer->blending));
2732
2733 if(configMdp(ctx->mOverlay, pargL, orient,
2734 cropL, dstL, metadata, lDest) < 0) {
2735 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2736 return -1;
2737 }
2738 }
2739
2740 //configure right pipe
2741 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002742 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002743 static_cast<eRotFlags>(rotFlags),
2744 layer->planeAlpha,
2745 (ovutils::eBlending) getBlending(layer->blending));
2746 if(configMdp(ctx->mOverlay, pargR, orient,
2747 cropR, dstR, metadata, rDest) < 0) {
2748 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2749 return -1;
2750 }
2751 }
2752
2753 return 0;
2754}
2755
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002756bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2757 Locker::Autolock _l(ctx->mDrawLock);
2758 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2759 char path[MAX_SYSFS_FILE_PATH];
2760 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2761 int fd = open(path, O_RDONLY);
2762 if(fd < 0) {
2763 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2764 return -1;
2765 }
2766 char value[4];
2767 ssize_t size_read = read(fd, value, sizeof(value)-1);
2768 if(size_read <= 0) {
2769 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2770 close(fd);
2771 return -1;
2772 }
2773 close(fd);
2774 value[size_read] = '\0';
2775 return atoi(value);
2776}
2777
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002778int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2779 Locker::Autolock _l(ctx->mDrawLock);
2780 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2781 char path[MAX_SYSFS_FILE_PATH];
2782 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2783 int fd = open(path, O_WRONLY);
2784 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002785 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002786 return -1;
2787 }
2788 char value[4];
2789 snprintf(value, sizeof(value), "%d", (int)enable);
2790 ssize_t ret = write(fd, value, strlen(value));
2791 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002792 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002793 close(fd);
2794 return -1;
2795 }
2796 close(fd);
2797 sIsPartialUpdateActive = enable;
2798 return 0;
2799}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002800}; //namespace
2801