blob: 937f156b33deac7248a8ae5da09b8f2785d88071 [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"
Saurabh Shahacf10202013-02-26 10:15:15 -080029
Saurabh Shah85234ec2013-04-12 17:09:00 -070030using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070031using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080032using namespace overlay::utils;
33namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035namespace qhwc {
36
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080037//==============MDPComp========================================================
38
Saurabh Shah59562ff2014-09-30 16:13:12 -070039IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080041bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050043bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070044bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070045int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080046int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070049MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070050 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
51 sSrcSplitEnabled = true;
52 return new MDPCompSrcSplit(dpy);
53 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070054 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080055 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070056 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080057}
58
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080059MDPComp::MDPComp(int dpy):mDpy(dpy){};
60
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070061void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080062{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070063 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
64 return;
65
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080066 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070067 (mDpy == 0) ? "\"PRIMARY\"" :
68 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070069 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
70 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080071 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
72 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
73 (mCurrentFrame.needsRedraw? "YES" : "NO"),
74 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070075 if(isDisplaySplit(ctx, mDpy)) {
76 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
77 "Right: [%d, %d, %d, %d] \n",
78 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
79 ctx->listStats[mDpy].lRoi.right,
80 ctx->listStats[mDpy].lRoi.bottom,
81 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
82 ctx->listStats[mDpy].rRoi.right,
83 ctx->listStats[mDpy].rRoi.bottom);
84 } else {
85 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
86 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
87 ctx->listStats[mDpy].lRoi.right,
88 ctx->listStats[mDpy].lRoi.bottom);
89 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080090 dumpsys_log(buf," --------------------------------------------- \n");
91 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
92 dumpsys_log(buf," --------------------------------------------- \n");
93 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
94 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
95 index,
96 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070097 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080098 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070099 (mCurrentFrame.drop[index] ? "DROP" :
100 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
102 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
103 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800104}
105
106bool MDPComp::init(hwc_context_t *ctx) {
107
108 if(!ctx) {
109 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
110 return false;
111 }
112
Saurabh Shah59562ff2014-09-30 16:13:12 -0700113 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114
115 sEnabled = false;
116 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800117 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
118 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800119 sEnabled = true;
120 }
121
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700122 sEnableMixedMode = true;
123 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
124 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
125 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
126 sEnableMixedMode = false;
127 }
128
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700130 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
131 int val = atoi(property);
132 if(val >= 0)
133 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800134 }
135
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400136 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700137 sIdleInvalidator = IdleInvalidator::getInstance();
138 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
139 delete sIdleInvalidator;
140 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400141 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800142 }
radhakrishnac9a67412013-09-25 17:40:42 +0530143
Saurabh Shah7c727642014-06-02 15:47:14 -0700144 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700145 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700146 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
147 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
148 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530149 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530150 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700151
152 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
153 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
154 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
155 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
156 HWC_DISPLAY_PRIMARY);
157 }
158
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700159 return true;
160}
161
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800162void MDPComp::reset(hwc_context_t *ctx) {
163 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700164 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800165 ctx->mOverlay->clear(mDpy);
166 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700167}
168
Raj Kamal4393eaa2014-06-06 13:45:20 +0530169void MDPComp::reset() {
170 sHandleTimeout = false;
171 mModeOn = false;
172}
173
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700174void MDPComp::timeout_handler(void *udata) {
175 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
176
177 if(!ctx) {
178 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
179 return;
180 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800181 Locker::Autolock _l(ctx->mDrawLock);
182 // Handle timeout event only if the previous composition is MDP or MIXED.
183 if(!sHandleTimeout) {
184 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
185 return;
186 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700187 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700188 ALOGE("%s: HWC proc not registered", __FUNCTION__);
189 return;
190 }
191 sIdleFallBack = true;
192 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700193 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700194}
195
Saurabh Shah59562ff2014-09-30 16:13:12 -0700196void MDPComp::setIdleTimeout(const uint32_t& timeout) {
197 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
198
199 if(sIdleInvalidator) {
200 if(timeout <= ONE_REFRESH_PERIOD_MS) {
201 //If the specified timeout is < 1 draw cycle worth, "virtually"
202 //disable idle timeout. The ideal way for clients to disable
203 //timeout is to set it to 0
204 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
205 ALOGI("Disabled idle timeout");
206 return;
207 }
208 sIdleInvalidator->setIdleTimeout(timeout);
209 ALOGI("Idle timeout set to %u", timeout);
210 } else {
211 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
212 }
213}
214
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800215void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800216 hwc_display_contents_1_t* list) {
217 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800218
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800220 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800221 if(!mCurrentFrame.isFBComposed[index]) {
222 layerProp[index].mFlags |= HWC_MDPCOMP;
223 layer->compositionType = HWC_OVERLAY;
224 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800225 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700226 /* Drop the layer when its already present in FB OR when it lies
227 * outside frame's ROI */
228 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800229 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700230 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800231 }
232 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700233}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500234
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800235void MDPComp::setRedraw(hwc_context_t *ctx,
236 hwc_display_contents_1_t* list) {
237 mCurrentFrame.needsRedraw = false;
238 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
239 (list->flags & HWC_GEOMETRY_CHANGED) ||
240 isSkipPresent(ctx, mDpy)) {
241 mCurrentFrame.needsRedraw = true;
242 }
243}
244
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700246 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700247 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800248}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800249
Saurabh Shahaa236822013-04-24 18:07:26 -0700250void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700251 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800252 if(mdpToLayer[i].pipeInfo) {
253 delete mdpToLayer[i].pipeInfo;
254 mdpToLayer[i].pipeInfo = NULL;
255 //We dont own the rotator
256 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800257 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800258 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800259
260 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
261 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700262 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263
Saurabh Shahaa236822013-04-24 18:07:26 -0700264 layerCount = numLayers;
265 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800266 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700267 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800268 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800269}
270
Saurabh Shahaa236822013-04-24 18:07:26 -0700271void MDPComp::FrameInfo::map() {
272 // populate layer and MDP maps
273 int mdpIdx = 0;
274 for(int idx = 0; idx < layerCount; idx++) {
275 if(!isFBComposed[idx]) {
276 mdpToLayer[mdpIdx].listIndex = idx;
277 layerToMDP[idx] = mdpIdx++;
278 }
279 }
280}
281
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800282MDPComp::LayerCache::LayerCache() {
283 reset();
284}
285
286void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700287 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530288 memset(&isFBComposed, true, sizeof(isFBComposed));
289 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800290 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700291}
292
293void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530294 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 for(int i = 0; i < numAppLayers; i++) {
296 hnd[i] = list->hwLayers[i].handle;
297 }
298}
299
300void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700301 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530302 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
303 memcpy(&drop, &curFrame.drop, sizeof(drop));
304}
305
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800306bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
307 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530308 if(layerCount != curFrame.layerCount)
309 return false;
310 for(int i = 0; i < curFrame.layerCount; i++) {
311 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
312 (curFrame.drop[i] != drop[i])) {
313 return false;
314 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800315 if(curFrame.isFBComposed[i] &&
316 (hnd[i] != list->hwLayers[i].handle)){
317 return false;
318 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530319 }
320 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800321}
322
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700323bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
324 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800325 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700326 (not isValidDimension(ctx,layer))
327 //More conditions here, SKIP, sRGB+Blend etc
328 ) {
329 return false;
330 }
331 return true;
332}
333
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530334bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800335 private_handle_t *hnd = (private_handle_t *)layer->handle;
336
337 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700338 if (layer->flags & HWC_COLOR_FILL) {
339 // Color layer
340 return true;
341 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700342 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800343 return false;
344 }
345
Naseer Ahmede850a802013-09-06 13:12:52 -0400346 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400347 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400348 return false;
349
Saurabh Shah62e1d732013-09-17 10:44:05 -0700350 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700351 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700352 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700353 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
354 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700355 int dst_w = dst.right - dst.left;
356 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800357 float w_scale = ((float)crop_w / (float)dst_w);
358 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530359 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700360
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800361 /* Workaround for MDP HW limitation in DSI command mode panels where
362 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
363 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530364 * There also is a HW limilation in MDP, minimum block size is 2x2
365 * Fallback to GPU if height is less than 2.
366 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700367 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800368 return false;
369
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800370 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530371 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800372 const float w_dscale = w_scale;
373 const float h_dscale = h_scale;
374
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800375 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700376
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530377 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700378 /* On targets that doesnt support Decimation (eg.,8x26)
379 * maximum downscale support is overlay pipe downscale.
380 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400381 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530382 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700383 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800384 return false;
385 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700386 // Decimation on macrotile format layers is not supported.
387 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530388 /* Bail out if
389 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700390 * 2. exceeds maximum downscale limit
391 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400392 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530393 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700394 w_dscale > maxMDPDownscale ||
395 h_dscale > maxMDPDownscale) {
396 return false;
397 }
398 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800399 return false;
400 }
401 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700402 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700403 return false;
404 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700405 }
406
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800407 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530408 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800409 const float w_uscale = 1.0f / w_scale;
410 const float h_uscale = 1.0f / h_scale;
411
412 if(w_uscale > upscale || h_uscale > upscale)
413 return false;
414 }
415
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800416 return true;
417}
418
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800419bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700420 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800421
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800422 if(!isEnabled()) {
423 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700424 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530425 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530426 qdutils::MDPVersion::getInstance().is8x16() ||
427 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800428 ctx->mVideoTransFlag &&
429 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700430 //1 Padding round to shift pipes across mixers
431 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
432 __FUNCTION__);
433 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700434 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
435 /* TODO: freeing up all the resources only for the targets having total
436 number of pipes < 8. Need to analyze number of VIG pipes used
437 for primary in previous draw cycle and accordingly decide
438 whether to fall back to full GPU comp or video only comp
439 */
440 if(isSecondaryConfiguring(ctx)) {
441 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
442 __FUNCTION__);
443 ret = false;
444 } else if(ctx->isPaddingRound) {
445 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
446 __FUNCTION__,mDpy);
447 ret = false;
448 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700449 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700450 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800451}
452
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800453void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
454 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
455 fbRect = getIntersection(fbRect, roi);
456}
457
458/* 1) Identify layers that are not visible or lying outside the updating ROI and
459 * drop them from composition.
460 * 2) If we have a scaling layer which needs cropping against generated
461 * ROI, reset ROI to full resolution. */
462bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
463 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800465 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800466
467 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800468 if(!isValidRect(visibleRect)) {
469 mCurrentFrame.drop[i] = true;
470 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800471 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800472 }
473
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700474 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700475 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800476 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700477
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700478 if(!isValidRect(res)) {
479 mCurrentFrame.drop[i] = true;
480 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800481 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700482 /* Reset frame ROI when any layer which needs scaling also needs ROI
483 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800484 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800485 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700486 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
487 mCurrentFrame.dropCount = 0;
488 return false;
489 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800490
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800491 /* deduct any opaque region from visibleRect */
492 if (layer->blending == HWC_BLENDING_NONE)
493 visibleRect = deductRect(visibleRect, res);
494 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700495 }
496 return true;
497}
498
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800499/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
500 * are updating. If DirtyRegion is applicable, calculate it by accounting all
501 * the changing layer's dirtyRegion. */
502void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
503 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700504 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800505 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 return;
507
508 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
510 (int)ctx->dpyAttr[mDpy].yres};
511
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700512 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800513 hwc_layer_1_t* layer = &list->hwLayers[index];
514 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800515 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700516 hwc_rect_t dst = layer->displayFrame;
517 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800518
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800519#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800520 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700521 {
522 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
523 int x_off = dst.left - src.left;
524 int y_off = dst.top - src.top;
525 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
526 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800527#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800529 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700530 }
531 }
532
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533 /* No layer is updating. Still SF wants a refresh.*/
534 if(!isValidRect(roi))
535 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800536
537 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800538 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800539
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 ctx->listStats[mDpy].lRoi = roi;
541 if(!validateAndApplyROI(ctx, list))
542 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700543
544 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800545 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
546 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
547}
548
549void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
550 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
551 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
552
553 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
554 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
555 fbRect = getUnion(l_fbRect, r_fbRect);
556}
557/* 1) Identify layers that are not visible or lying outside BOTH the updating
558 * ROI's and drop them from composition. If a layer is spanning across both
559 * the halves of the screen but needed by only ROI, the non-contributing
560 * half will not be programmed for MDP.
561 * 2) If we have a scaling layer which needs cropping against generated
562 * ROI, reset ROI to full resolution. */
563bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
564 hwc_display_contents_1_t* list) {
565
566 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
567
568 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
569 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
570
571 for(int i = numAppLayers - 1; i >= 0; i--){
572 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
573 {
574 mCurrentFrame.drop[i] = true;
575 mCurrentFrame.dropCount++;
576 continue;
577 }
578
579 const hwc_layer_1_t* layer = &list->hwLayers[i];
580 hwc_rect_t dstRect = layer->displayFrame;
581
582 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
583 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
584 hwc_rect_t res = getUnion(l_res, r_res);
585
586 if(!isValidRect(l_res) && !isValidRect(r_res)) {
587 mCurrentFrame.drop[i] = true;
588 mCurrentFrame.dropCount++;
589 } else {
590 /* Reset frame ROI when any layer which needs scaling also needs ROI
591 * cropping */
592 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
593 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
594 mCurrentFrame.dropCount = 0;
595 return false;
596 }
597
598 if (layer->blending == HWC_BLENDING_NONE) {
599 visibleRectL = deductRect(visibleRectL, l_res);
600 visibleRectR = deductRect(visibleRectR, r_res);
601 }
602 }
603 }
604 return true;
605}
606/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
607 * are updating. If DirtyRegion is applicable, calculate it by accounting all
608 * the changing layer's dirtyRegion. */
609void MDPCompSplit::generateROI(hwc_context_t *ctx,
610 hwc_display_contents_1_t* list) {
611 if(!canPartialUpdate(ctx, list))
612 return;
613
614 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
615 int lSplit = getLeftSplit(ctx, mDpy);
616
617 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
618 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
619
620 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
621 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
622
623 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
624 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
625
626 for(int index = 0; index < numAppLayers; index++ ) {
627 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800628 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800629 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800630 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700631 hwc_rect_t dst = layer->displayFrame;
632 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800633
634#ifdef QCOM_BSP
635 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700636 {
637 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
638 int x_off = dst.left - src.left;
639 int y_off = dst.top - src.top;
640 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
641 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800642#endif
643
644 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
645 if(isValidRect(l_dst))
646 l_roi = getUnion(l_roi, l_dst);
647
648 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
649 if(isValidRect(r_dst))
650 r_roi = getUnion(r_roi, r_dst);
651 }
652 }
653
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700654 /* For panels that cannot accept commands in both the interfaces, we cannot
655 * send two ROI's (for each half). We merge them into single ROI and split
656 * them across lSplit for MDP mixer use. The ROI's will be merged again
657 * finally before udpating the panel in the driver. */
658 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
659 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
660 l_roi = getIntersection(temp_roi, l_frame);
661 r_roi = getIntersection(temp_roi, r_frame);
662 }
663
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800664 /* No layer is updating. Still SF wants a refresh. */
665 if(!isValidRect(l_roi) && !isValidRect(r_roi))
666 return;
667
668 l_roi = getSanitizeROI(l_roi, l_frame);
669 r_roi = getSanitizeROI(r_roi, r_frame);
670
671 ctx->listStats[mDpy].lRoi = l_roi;
672 ctx->listStats[mDpy].rRoi = r_roi;
673
674 if(!validateAndApplyROI(ctx, list))
675 resetROI(ctx, mDpy);
676
677 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
678 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
679 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
680 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
681 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
682 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700683}
684
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800685/* Checks for conditions where all the layers marked for MDP comp cannot be
686 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800687bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800688 hwc_display_contents_1_t* list){
689
Saurabh Shahaa236822013-04-24 18:07:26 -0700690 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800691 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800692
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700693 // No Idle fall back, if secure display or secure RGB layers are present
694 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
695 !ctx->listStats[mDpy].secureRGBCount)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700696 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
697 return false;
698 }
699
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800700 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700701 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
702 __FUNCTION__,
703 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800704 return false;
705 }
706
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700707 // if secondary is configuring or Padding round, fall back to video only
708 // composition and release all assigned non VIG pipes from primary.
709 if(isSecondaryConfiguring(ctx)) {
710 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
711 __FUNCTION__);
712 return false;
713 } else if(ctx->isPaddingRound) {
714 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
715 __FUNCTION__,mDpy);
716 return false;
717 }
718
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530719 MDPVersion& mdpHw = MDPVersion::getInstance();
720 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400721 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530722 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800723 // Disable MDP comp on Secondary when the primary is highres panel and
724 // the secondary is a normal 1080p, because, MDP comp on secondary under
725 // in such usecase, decimation gets used for downscale and there will be
726 // a quality mismatch when there will be a fallback to GPU comp
727 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
728 __FUNCTION__);
729 return false;
730 }
731
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700732 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800733 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700734 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800735 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
736 return false;
737 }
738
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800739 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800740 hwc_layer_1_t* layer = &list->hwLayers[i];
741 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800742
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800743 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700744 if(!canUseRotator(ctx, mDpy)) {
745 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
746 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700747 return false;
748 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800749 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530750
751 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
752 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700753 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530754 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
755 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
756 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800757 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700758
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700759 if(ctx->mAD->isDoable()) {
760 return false;
761 }
762
Saurabh Shahaa236822013-04-24 18:07:26 -0700763 //If all above hard conditions are met we can do full or partial MDP comp.
764 bool ret = false;
765 if(fullMDPComp(ctx, list)) {
766 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700767 } else if(fullMDPCompWithPTOR(ctx, list)) {
768 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700769 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700770 ret = true;
771 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530772
Saurabh Shahaa236822013-04-24 18:07:26 -0700773 return ret;
774}
775
776bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700777
778 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
779 return false;
780
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700781 //Will benefit presentation / secondary-only layer.
782 if((mDpy > HWC_DISPLAY_PRIMARY) &&
783 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
784 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
785 return false;
786 }
787
788 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
789 for(int i = 0; i < numAppLayers; i++) {
790 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700791 if(not mCurrentFrame.drop[i] and
792 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700793 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
794 return false;
795 }
796 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800797
Saurabh Shahaa236822013-04-24 18:07:26 -0700798 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700799 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
800 sizeof(mCurrentFrame.isFBComposed));
801 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
802 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700803
Raj Kamal389d6e32014-08-04 14:43:24 +0530804 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800805 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530806 }
807
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800808 if(!postHeuristicsHandling(ctx, list)) {
809 ALOGD_IF(isDebug(), "post heuristic handling failed");
810 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700811 return false;
812 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700813 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
814 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700815 return true;
816}
817
Sushil Chauhandefd3522014-05-13 18:17:12 -0700818/* Full MDP Composition with Peripheral Tiny Overlap Removal.
819 * MDP bandwidth limitations can be avoided, if the overlap region
820 * covered by the smallest layer at a higher z-order, gets composed
821 * by Copybit on a render buffer, which can be queued to MDP.
822 */
823bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
824 hwc_display_contents_1_t* list) {
825
826 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
827 const int stagesForMDP = min(sMaxPipesPerMixer,
828 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
829
830 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700831 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700832 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
833 return false;
834 }
835
836 // Frame level checks
837 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
838 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
839 isSecurePresent(ctx, mDpy)) {
840 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
841 return false;
842 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700843 // MDP comp checks
844 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700845 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700846 if(not isSupportedForMDPComp(ctx, layer)) {
847 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
848 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700849 }
850 }
851
Sushil Chauhandefd3522014-05-13 18:17:12 -0700852 /* We cannot use this composition mode, if:
853 1. A below layer needs scaling.
854 2. Overlap is not peripheral to display.
855 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700856 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700857 */
858
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700859 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
860 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
861 memset(overlapRect, 0, sizeof(overlapRect));
862 int layerPixelCount, minPixelCount = 0;
863 int numPTORLayersFound = 0;
864 for (int i = numAppLayers-1; (i >= 0 &&
865 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700866 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700867 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700868 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700869 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
870 // PTOR layer should be peripheral and cannot have transform
871 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
872 has90Transform(layer)) {
873 continue;
874 }
875 if((3 * (layerPixelCount + minPixelCount)) >
876 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
877 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
878 continue;
879 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700880 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700881 for (int j = i-1; j >= 0; j--) {
882 // Check if the layers below this layer qualifies for PTOR comp
883 hwc_layer_1_t* layer = &list->hwLayers[j];
884 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700885 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700886 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700887 if (isValidRect(getIntersection(dispFrame, disFrame))) {
888 if (has90Transform(layer) || needsScaling(layer)) {
889 found = false;
890 break;
891 }
892 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700893 }
894 }
895 // Store the minLayer Index
896 if(found) {
897 minLayerIndex[numPTORLayersFound] = i;
898 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
899 minPixelCount += layerPixelCount;
900 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700901 }
902 }
903
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700904 // No overlap layers
905 if (!numPTORLayersFound)
906 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700907
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700908 // Store the displayFrame and the sourceCrops of the layers
909 hwc_rect_t displayFrame[numAppLayers];
910 hwc_rect_t sourceCrop[numAppLayers];
911 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700912 hwc_layer_1_t* layer = &list->hwLayers[i];
913 displayFrame[i] = layer->displayFrame;
914 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700915 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700916
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530917 /**
918 * It's possible that 2 PTOR layers might have overlapping.
919 * In such case, remove the intersection(again if peripheral)
920 * from the lower PTOR layer to avoid overlapping.
921 * If intersection is not on peripheral then compromise
922 * by reducing number of PTOR layers.
923 **/
924 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
925 if(isValidRect(commonRect)) {
926 overlapRect[1] = deductRect(overlapRect[1], commonRect);
927 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
928 }
929
930 ctx->mPtorInfo.count = numPTORLayersFound;
931 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
932 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
933 }
934
935 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
936 // reset PTOR
937 ctx->mPtorInfo.count = 0;
938 if(isValidRect(commonRect)) {
939 // If PTORs are intersecting restore displayframe of PTOR[1]
940 // before returning, as we have modified it above.
941 list->hwLayers[minLayerIndex[1]].displayFrame =
942 displayFrame[minLayerIndex[1]];
943 }
944 return false;
945 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700946 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
947 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
948
Xu Yangcda012c2014-07-30 21:57:21 +0800949 // Store the blending mode, planeAlpha, and transform of PTOR layers
950 int32_t blending[numPTORLayersFound];
951 uint8_t planeAlpha[numPTORLayersFound];
952 uint32_t transform[numPTORLayersFound];
953
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700954 for(int j = 0; j < numPTORLayersFound; j++) {
955 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700956
957 // Update src crop of PTOR layer
958 hwc_layer_1_t* layer = &list->hwLayers[index];
959 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
960 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
961 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
962 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
963
964 // Store & update w, h, format of PTOR layer
965 private_handle_t *hnd = (private_handle_t *)layer->handle;
966 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
967 layerWhf[j] = whf;
968 hnd->width = renderBuf->width;
969 hnd->height = renderBuf->height;
970 hnd->format = renderBuf->format;
971
Xu Yangcda012c2014-07-30 21:57:21 +0800972 // Store & update blending mode, planeAlpha and transform of PTOR layer
973 blending[j] = layer->blending;
974 planeAlpha[j] = layer->planeAlpha;
975 transform[j] = layer->transform;
976 layer->blending = HWC_BLENDING_NONE;
977 layer->planeAlpha = 0xFF;
978 layer->transform = 0;
979
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700980 // Remove overlap from crop & displayFrame of below layers
981 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700982 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 if(!isValidRect(getIntersection(layer->displayFrame,
984 overlapRect[j]))) {
985 continue;
986 }
987 // Update layer attributes
988 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
989 hwc_rect_t destRect = deductRect(layer->displayFrame,
990 overlapRect[j]);
991 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
992 layer->transform);
993 layer->sourceCropf.left = (float)srcCrop.left;
994 layer->sourceCropf.top = (float)srcCrop.top;
995 layer->sourceCropf.right = (float)srcCrop.right;
996 layer->sourceCropf.bottom = (float)srcCrop.bottom;
997 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700998 }
999
1000 mCurrentFrame.mdpCount = numAppLayers;
1001 mCurrentFrame.fbCount = 0;
1002 mCurrentFrame.fbZ = -1;
1003
1004 for (int j = 0; j < numAppLayers; j++)
1005 mCurrentFrame.isFBComposed[j] = false;
1006
1007 bool result = postHeuristicsHandling(ctx, list);
1008
1009 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001010 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001011 hwc_layer_1_t* layer = &list->hwLayers[i];
1012 layer->displayFrame = displayFrame[i];
1013 layer->sourceCropf.left = (float)sourceCrop[i].left;
1014 layer->sourceCropf.top = (float)sourceCrop[i].top;
1015 layer->sourceCropf.right = (float)sourceCrop[i].right;
1016 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1017 }
1018
Xu Yangcda012c2014-07-30 21:57:21 +08001019 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001020 for (int i = 0; i < numPTORLayersFound; i++) {
1021 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001022 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001023 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1024 hnd->width = layerWhf[i].w;
1025 hnd->height = layerWhf[i].h;
1026 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001027 layer->blending = blending[i];
1028 layer->planeAlpha = planeAlpha[i];
1029 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001030 }
1031
Sushil Chauhandefd3522014-05-13 18:17:12 -07001032 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001033 // reset PTOR
1034 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001035 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001036 } else {
1037 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1038 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001039 }
1040
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001041 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1042 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001043 return result;
1044}
1045
Saurabh Shahaa236822013-04-24 18:07:26 -07001046bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1047{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001048 if(!sEnableMixedMode) {
1049 //Mixed mode is disabled. No need to even try caching.
1050 return false;
1051 }
1052
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001053 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001054 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001055 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001056 cacheBasedComp(ctx, list);
1057 } else {
1058 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001059 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001060 }
1061
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001062 return ret;
1063}
1064
1065bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1066 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001067 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1068 return false;
1069
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001070 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001071 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001072 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001073
1074 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1075 for(int i = 0; i < numAppLayers; i++) {
1076 if(!mCurrentFrame.isFBComposed[i]) {
1077 hwc_layer_1_t* layer = &list->hwLayers[i];
1078 if(not isSupportedForMDPComp(ctx, layer)) {
1079 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1080 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001081 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001082 return false;
1083 }
1084 }
1085 }
1086
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001087 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001088 /* mark secure RGB layers for MDP comp */
1089 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301090 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001091 if(!ret) {
1092 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001093 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001094 return false;
1095 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001096
1097 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001098
Raj Kamal389d6e32014-08-04 14:43:24 +05301099 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001100 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301101 }
1102
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001103 //Will benefit cases where a video has non-updating background.
1104 if((mDpy > HWC_DISPLAY_PRIMARY) and
1105 (mdpCount > MAX_SEC_LAYERS)) {
1106 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001107 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001108 return false;
1109 }
1110
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001111 if(!postHeuristicsHandling(ctx, list)) {
1112 ALOGD_IF(isDebug(), "post heuristic handling failed");
1113 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001114 return false;
1115 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001116 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1117 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001118
Saurabh Shahaa236822013-04-24 18:07:26 -07001119 return true;
1120}
1121
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001122bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001123 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001124 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1125 return false;
1126
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001127 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001128 return false;
1129 }
1130
Saurabh Shahb772ae32013-11-18 15:40:02 -08001131 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001132 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1133 const int stagesForMDP = min(sMaxPipesPerMixer,
1134 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001135
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001136 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1137 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1138 int lastMDPSupportedIndex = numAppLayers;
1139 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001140
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001141 //Find the minimum MDP batch size
1142 for(int i = 0; i < numAppLayers;i++) {
1143 if(mCurrentFrame.drop[i]) {
1144 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001145 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001146 }
1147 hwc_layer_1_t* layer = &list->hwLayers[i];
1148 if(not isSupportedForMDPComp(ctx, layer)) {
1149 lastMDPSupportedIndex = i;
1150 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1151 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001152 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001153 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001154 }
1155
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001156 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1157 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1158 mCurrentFrame.dropCount);
1159
1160 //Start at a point where the fb batch should at least have 2 layers, for
1161 //this mode to be justified.
1162 while(fbBatchSize < 2) {
1163 ++fbBatchSize;
1164 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001165 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001166
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001167 //If there are no layers for MDP, this mode doesnt make sense.
1168 if(mdpBatchSize < 1) {
1169 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1170 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001171 return false;
1172 }
1173
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001174 mCurrentFrame.reset(numAppLayers);
1175
1176 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1177 while(mdpBatchSize > 0) {
1178 //Mark layers for MDP comp
1179 int mdpBatchLeft = mdpBatchSize;
1180 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1181 if(mCurrentFrame.drop[i]) {
1182 continue;
1183 }
1184 mCurrentFrame.isFBComposed[i] = false;
1185 --mdpBatchLeft;
1186 }
1187
1188 mCurrentFrame.fbZ = mdpBatchSize;
1189 mCurrentFrame.fbCount = fbBatchSize;
1190 mCurrentFrame.mdpCount = mdpBatchSize;
1191
1192 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1193 __FUNCTION__, mdpBatchSize, fbBatchSize,
1194 mCurrentFrame.dropCount);
1195
1196 if(postHeuristicsHandling(ctx, list)) {
1197 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001198 __FUNCTION__);
1199 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1200 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001201 return true;
1202 }
1203
1204 reset(ctx);
1205 --mdpBatchSize;
1206 ++fbBatchSize;
1207 }
1208
1209 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001210}
1211
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001212bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301213 if(mDpy or isSecurePresent(ctx, mDpy) or
1214 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001215 return false;
1216 }
1217 return true;
1218}
1219
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001220bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1221 hwc_display_contents_1_t* list){
1222 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1223 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1224 mDpy ) {
1225 return false;
1226 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001227 if(ctx->listStats[mDpy].secureUI)
1228 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001229 return true;
1230}
1231
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001232bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1233 hwc_display_contents_1_t* list) {
1234 const bool secureOnly = true;
1235 return videoOnlyComp(ctx, list, not secureOnly) or
1236 videoOnlyComp(ctx, list, secureOnly);
1237}
1238
1239bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001240 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001241 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1242 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001243 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001244
Saurabh Shahaa236822013-04-24 18:07:26 -07001245 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001246 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001247 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001248 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001249
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001250 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1251 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001252 return false;
1253 }
1254
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001255 /* Bail out if we are processing only secured video layers
1256 * and we dont have any */
1257 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001258 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001259 return false;
1260 }
1261
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001262 if(mCurrentFrame.fbCount)
1263 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001264
Raj Kamal389d6e32014-08-04 14:43:24 +05301265 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001266 adjustForSourceSplit(ctx, list);
1267 }
1268
1269 if(!postHeuristicsHandling(ctx, list)) {
1270 ALOGD_IF(isDebug(), "post heuristic handling failed");
1271 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001272 return false;
1273 }
1274
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001275 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1276 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001277 return true;
1278}
1279
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001280/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1281bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1282 hwc_display_contents_1_t* list) {
1283 const bool secureOnly = true;
1284 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1285 mdpOnlyLayersComp(ctx, list, secureOnly);
1286
1287}
1288
1289bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1290 hwc_display_contents_1_t* list, bool secureOnly) {
1291
1292 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1293 return false;
1294
1295 /* Bail out if we are processing only secured video layers
1296 * and we dont have any */
1297 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1298 reset(ctx);
1299 return false;
1300 }
1301
1302 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1303 mCurrentFrame.reset(numAppLayers);
1304 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1305
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001306 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001307 /* mark secure RGB layers for MDP comp */
1308 updateSecureRGB(ctx, list);
1309
1310 if(mCurrentFrame.mdpCount == 0) {
1311 reset(ctx);
1312 return false;
1313 }
1314
1315 /* find the maximum batch of layers to be marked for framebuffer */
1316 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1317 if(!ret) {
1318 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1319 reset(ctx);
1320 return false;
1321 }
1322
1323 if(sEnableYUVsplit){
1324 adjustForSourceSplit(ctx, list);
1325 }
1326
1327 if(!postHeuristicsHandling(ctx, list)) {
1328 ALOGD_IF(isDebug(), "post heuristic handling failed");
1329 reset(ctx);
1330 return false;
1331 }
1332
1333 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1334 __FUNCTION__);
1335 return true;
1336}
1337
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001338/* Checks for conditions where YUV layers cannot be bypassed */
1339bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001340 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001341 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001342 return false;
1343 }
1344
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001345 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001346 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1347 return false;
1348 }
1349
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001350 if(isSecuring(ctx, layer)) {
1351 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1352 return false;
1353 }
1354
Saurabh Shah4fdde762013-04-30 18:47:33 -07001355 if(!isValidDimension(ctx, layer)) {
1356 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1357 __FUNCTION__);
1358 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001359 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001360
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001361 if(layer->planeAlpha < 0xFF) {
1362 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1363 in video only mode",
1364 __FUNCTION__);
1365 return false;
1366 }
1367
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001368 return true;
1369}
1370
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001371/* Checks for conditions where Secure RGB layers cannot be bypassed */
1372bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1373 if(isSkipLayer(layer)) {
1374 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1375 __FUNCTION__, mDpy);
1376 return false;
1377 }
1378
1379 if(isSecuring(ctx, layer)) {
1380 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1381 return false;
1382 }
1383
1384 if(not isSupportedForMDPComp(ctx, layer)) {
1385 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1386 __FUNCTION__);
1387 return false;
1388 }
1389 return true;
1390}
1391
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301392/* starts at fromIndex and check for each layer to find
1393 * if it it has overlapping with any Updating layer above it in zorder
1394 * till the end of the batch. returns true if it finds any intersection */
1395bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1396 int fromIndex, int toIndex) {
1397 for(int i = fromIndex; i < toIndex; i++) {
1398 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1399 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1400 return false;
1401 }
1402 }
1403 }
1404 return true;
1405}
1406
1407/* Checks if given layer at targetLayerIndex has any
1408 * intersection with all the updating layers in beween
1409 * fromIndex and toIndex. Returns true if it finds intersectiion */
1410bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1411 int fromIndex, int toIndex, int targetLayerIndex) {
1412 for(int i = fromIndex; i <= toIndex; i++) {
1413 if(!mCurrentFrame.isFBComposed[i]) {
1414 if(areLayersIntersecting(&list->hwLayers[i],
1415 &list->hwLayers[targetLayerIndex])) {
1416 return true;
1417 }
1418 }
1419 }
1420 return false;
1421}
1422
1423int MDPComp::getBatch(hwc_display_contents_1_t* list,
1424 int& maxBatchStart, int& maxBatchEnd,
1425 int& maxBatchCount) {
1426 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301427 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001428 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301429 while (i < mCurrentFrame.layerCount) {
1430 int batchCount = 0;
1431 int batchStart = i;
1432 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001433 /* Adjust batch Z order with the dropped layers so far */
1434 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301435 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301436 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301437 while(i < mCurrentFrame.layerCount) {
1438 if(!mCurrentFrame.isFBComposed[i]) {
1439 if(!batchCount) {
1440 i++;
1441 break;
1442 }
1443 updatingLayersAbove++;
1444 i++;
1445 continue;
1446 } else {
1447 if(mCurrentFrame.drop[i]) {
1448 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001449 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301450 continue;
1451 } else if(updatingLayersAbove <= 0) {
1452 batchCount++;
1453 batchEnd = i;
1454 i++;
1455 continue;
1456 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1457
1458 // We have a valid updating layer already. If layer-i not
1459 // have overlapping with all updating layers in between
1460 // batch-start and i, then we can add layer i to batch.
1461 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1462 batchCount++;
1463 batchEnd = i;
1464 i++;
1465 continue;
1466 } else if(canPushBatchToTop(list, batchStart, i)) {
1467 //If All the non-updating layers with in this batch
1468 //does not have intersection with the updating layers
1469 //above in z-order, then we can safely move the batch to
1470 //higher z-order. Increment fbZ as it is moving up.
1471 if( firstZReverseIndex < 0) {
1472 firstZReverseIndex = i;
1473 }
1474 batchCount++;
1475 batchEnd = i;
1476 fbZ += updatingLayersAbove;
1477 i++;
1478 updatingLayersAbove = 0;
1479 continue;
1480 } else {
1481 //both failed.start the loop again from here.
1482 if(firstZReverseIndex >= 0) {
1483 i = firstZReverseIndex;
1484 }
1485 break;
1486 }
1487 }
1488 }
1489 }
1490 if(batchCount > maxBatchCount) {
1491 maxBatchCount = batchCount;
1492 maxBatchStart = batchStart;
1493 maxBatchEnd = batchEnd;
1494 fbZOrder = fbZ;
1495 }
1496 }
1497 return fbZOrder;
1498}
1499
1500bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1501 hwc_display_contents_1_t* list) {
1502 /* Idea is to keep as many non-updating(cached) layers in FB and
1503 * send rest of them through MDP. This is done in 2 steps.
1504 * 1. Find the maximum contiguous batch of non-updating layers.
1505 * 2. See if we can improve this batch size for caching by adding
1506 * opaque layers around the batch, if they don't have
1507 * any overlapping with the updating layers in between.
1508 * NEVER mark an updating layer for caching.
1509 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001510
1511 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001512 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001513 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301514 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001515
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001516 /* Nothing is cached. No batching needed */
1517 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001518 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001519 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001520
1521 /* No MDP comp layers, try to use other comp modes */
1522 if(mCurrentFrame.mdpCount == 0) {
1523 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001524 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001525
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301526 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001527
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001529 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001530 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001531 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301532 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001533 if(!mCurrentFrame.drop[i]){
1534 //If an unsupported layer is being attempted to
1535 //be pulled out we should fail
1536 if(not isSupportedForMDPComp(ctx, layer)) {
1537 return false;
1538 }
1539 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001540 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001541 }
1542 }
1543
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301544 // update the frame data
1545 mCurrentFrame.fbZ = fbZ;
1546 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001547 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001548 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001549
1550 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301551 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001552
1553 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001554}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001555
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001556void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001557 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001558 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001559 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001560
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001561 for(int i = 0; i < numAppLayers; i++) {
1562 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001563 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001564 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001565 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001566 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001567 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001568 }
1569 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001570
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001571 frame.fbCount = fbCount;
1572 frame.mdpCount = frame.layerCount - frame.fbCount
1573 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001574
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001575 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1576 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577}
1578
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001579void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001580 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001581 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1582 for(int index = 0;index < nYuvCount; index++){
1583 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1584 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1585
1586 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001587 if(!frame.isFBComposed[nYuvIndex]) {
1588 frame.isFBComposed[nYuvIndex] = true;
1589 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001590 }
1591 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001592 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001593 private_handle_t *hnd = (private_handle_t *)layer->handle;
1594 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001595 frame.isFBComposed[nYuvIndex] = false;
1596 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001597 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001598 }
1599 }
1600 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001601
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001602 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1603 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604}
1605
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001606void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1607 hwc_display_contents_1_t* list) {
1608 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1609 for(int index = 0;index < nSecureRGBCount; index++){
1610 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1611 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1612
1613 if(!isSecureRGBDoable(ctx, layer)) {
1614 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1615 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1616 mCurrentFrame.fbCount++;
1617 }
1618 } else {
1619 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1620 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1621 mCurrentFrame.fbCount--;
1622 }
1623 }
1624 }
1625
1626 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1627 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1628 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1629 mCurrentFrame.fbCount);
1630}
1631
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001632hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1633 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001634 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001635
1636 /* Update only the region of FB needed for composition */
1637 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1638 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1639 hwc_layer_1_t* layer = &list->hwLayers[i];
1640 hwc_rect_t dst = layer->displayFrame;
1641 fbRect = getUnion(fbRect, dst);
1642 }
1643 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001644 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001645 return fbRect;
1646}
1647
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001648bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1649 hwc_display_contents_1_t* list) {
1650
1651 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001652 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001653 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1654 return false;
1655 }
1656
1657 //Limitations checks
1658 if(!hwLimitationsCheck(ctx, list)) {
1659 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1660 return false;
1661 }
1662
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001663 //Configure framebuffer first if applicable
1664 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001665 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001666 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1667 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001668 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1669 __FUNCTION__);
1670 return false;
1671 }
1672 }
1673
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001674 mCurrentFrame.map();
1675
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001676 if(!allocLayerPipes(ctx, list)) {
1677 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001678 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001679 }
1680
1681 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001682 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001683 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001684 int mdpIndex = mCurrentFrame.layerToMDP[index];
1685 hwc_layer_1_t* layer = &list->hwLayers[index];
1686
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301687 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1688 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1689 mdpNextZOrder++;
1690 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001691 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1692 cur_pipe->zOrder = mdpNextZOrder++;
1693
radhakrishnac9a67412013-09-25 17:40:42 +05301694 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301695 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301696 if(configure4k2kYuv(ctx, layer,
1697 mCurrentFrame.mdpToLayer[mdpIndex])
1698 != 0 ){
1699 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1700 for layer %d",__FUNCTION__, index);
1701 return false;
1702 }
1703 else{
1704 mdpNextZOrder++;
1705 }
1706 continue;
1707 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1709 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301710 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001711 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001712 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001713 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001714 }
1715
Saurabh Shaha36be922013-12-16 18:18:39 -08001716 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1717 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1718 ,__FUNCTION__, mDpy);
1719 return false;
1720 }
1721
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001722 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001723 return true;
1724}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001725
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001726bool MDPComp::resourceCheck(hwc_context_t* ctx,
1727 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001728 const bool fbUsed = mCurrentFrame.fbCount;
1729 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1730 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1731 return false;
1732 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001733 // Init rotCount to number of rotate sessions used by other displays
1734 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1735 // Count the number of rotator sessions required for current display
1736 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1737 if(!mCurrentFrame.isFBComposed[index]) {
1738 hwc_layer_1_t* layer = &list->hwLayers[index];
1739 private_handle_t *hnd = (private_handle_t *)layer->handle;
1740 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1741 rotCount++;
1742 }
1743 }
1744 }
1745 // if number of layers to rotate exceeds max rotator sessions, bail out.
1746 if(rotCount > RotMgr::MAX_ROT_SESS) {
1747 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1748 __FUNCTION__, mDpy);
1749 return false;
1750 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001751 return true;
1752}
1753
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301754bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1755 hwc_display_contents_1_t* list) {
1756
1757 //A-family hw limitation:
1758 //If a layer need alpha scaling, MDP can not support.
1759 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1760 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1761 if(!mCurrentFrame.isFBComposed[i] &&
1762 isAlphaScaled( &list->hwLayers[i])) {
1763 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1764 return false;
1765 }
1766 }
1767 }
1768
1769 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1770 //If multiple layers requires downscaling and also they are overlapping
1771 //fall back to GPU since MDSS can not handle it.
1772 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1773 qdutils::MDPVersion::getInstance().is8x26()) {
1774 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1775 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1776 if(!mCurrentFrame.isFBComposed[i] &&
1777 isDownscaleRequired(botLayer)) {
1778 //if layer-i is marked for MDP and needs downscaling
1779 //check if any MDP layer on top of i & overlaps with layer-i
1780 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1781 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1782 if(!mCurrentFrame.isFBComposed[j] &&
1783 isDownscaleRequired(topLayer)) {
1784 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1785 topLayer->displayFrame);
1786 if(isValidRect(r))
1787 return false;
1788 }
1789 }
1790 }
1791 }
1792 }
1793 return true;
1794}
1795
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001796int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001797 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001798 char property[PROPERTY_VALUE_MAX];
1799
Raj Kamal4393eaa2014-06-06 13:45:20 +05301800 if(!ctx || !list) {
1801 ALOGE("%s: Invalid context or list",__FUNCTION__);
1802 mCachedFrame.reset();
1803 return -1;
1804 }
1805
1806 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001807 if(mDpy == HWC_DISPLAY_PRIMARY) {
1808 sSimulationFlags = 0;
1809 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1810 int currentFlags = atoi(property);
1811 if(currentFlags != sSimulationFlags) {
1812 sSimulationFlags = currentFlags;
1813 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1814 sSimulationFlags, sSimulationFlags);
1815 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001816 }
1817 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001818 // reset PTOR
1819 if(!mDpy)
1820 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001821
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301822 //Do not cache the information for next draw cycle.
1823 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1824 ALOGI("%s: Unsupported layer count for mdp composition",
1825 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001826 mCachedFrame.reset();
1827 return -1;
1828 }
1829
Saurabh Shahb39f8152013-08-22 10:21:44 -07001830 //reset old data
1831 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001832 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1833 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301834
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001835 // Detect the start of animation and fall back to GPU only once to cache
1836 // all the layers in FB and display FB content untill animation completes.
1837 if(ctx->listStats[mDpy].isDisplayAnimating) {
1838 mCurrentFrame.needsRedraw = false;
1839 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1840 mCurrentFrame.needsRedraw = true;
1841 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1842 }
1843 setMDPCompLayerFlags(ctx, list);
1844 mCachedFrame.updateCounts(mCurrentFrame);
1845 ret = -1;
1846 return ret;
1847 } else {
1848 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1849 }
1850
Saurabh Shahb39f8152013-08-22 10:21:44 -07001851 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001852 if(isFrameDoable(ctx)) {
1853 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001854
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001855 // if tryFullFrame fails, try to push all video and secure RGB layers
1856 // to MDP for composition.
1857 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1858 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301859 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001860 setMDPCompLayerFlags(ctx, list);
1861 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001862 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001863 reset(ctx);
1864 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1865 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001866 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001867 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1868 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001869 }
1870 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001871 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1872 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001873 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001874 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001875
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001876 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001877 ALOGD("GEOMETRY change: %d",
1878 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001879 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001880 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001881 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001882 }
1883
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001884#ifdef DYNAMIC_FPS
1885 //For primary display, set the dynamic refreshrate
1886 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1887 FrameInfo frame;
1888 frame.reset(mCurrentFrame.layerCount);
1889 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1890 __FUNCTION__);
1891 updateLayerCache(ctx, list, frame);
1892 updateYUV(ctx, list, false /*secure only*/, frame);
1893 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1894 //Set the new fresh rate, if there is only one updating YUV layer
1895 //or there is one single RGB layer with this request
1896 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1897 (frame.layerCount == 1)) {
1898 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1899 }
1900 setRefreshRate(ctx, mDpy, refreshRate);
1901 }
1902#endif
1903
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001904 mCachedFrame.cacheAll(list);
1905 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001906 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001907}
1908
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001909bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301910
1911 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301912 int mdpIndex = mCurrentFrame.layerToMDP[index];
1913 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1914 info.pipeInfo = new MdpYUVPipeInfo;
1915 info.rot = NULL;
1916 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301917
1918 pipe_info.lIndex = ovutils::OV_INVALID;
1919 pipe_info.rIndex = ovutils::OV_INVALID;
1920
Saurabh Shahc62f3982014-03-05 14:28:26 -08001921 Overlay::PipeSpecs pipeSpecs;
1922 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1923 pipeSpecs.needsScaling = true;
1924 pipeSpecs.dpy = mDpy;
1925 pipeSpecs.fb = false;
1926
1927 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301928 if(pipe_info.lIndex == ovutils::OV_INVALID){
1929 bRet = false;
1930 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1931 __FUNCTION__);
1932 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001933 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301934 if(pipe_info.rIndex == ovutils::OV_INVALID){
1935 bRet = false;
1936 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1937 __FUNCTION__);
1938 }
1939 return bRet;
1940}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001941
1942int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1943 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001944 if (ctx->mPtorInfo.isActive()) {
1945 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001946 if (fd < 0) {
1947 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001948 }
1949 }
1950 return fd;
1951}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001952//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001953
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001954void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301955 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001956 //If 4k2k Yuv layer split is possible, and if
1957 //fbz is above 4k2k layer, increment fb zorder by 1
1958 //as we split 4k2k layer and increment zorder for right half
1959 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001960 if(!ctx)
1961 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001962 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301963 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1964 index++) {
1965 if(!mCurrentFrame.isFBComposed[index]) {
1966 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1967 mdpNextZOrder++;
1968 }
1969 mdpNextZOrder++;
1970 hwc_layer_1_t* layer = &list->hwLayers[index];
1971 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301972 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301973 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1974 mCurrentFrame.fbZ += 1;
1975 mdpNextZOrder++;
1976 //As we split 4kx2k yuv layer and program to 2 VG pipes
1977 //(if available) increase mdpcount by 1.
1978 mCurrentFrame.mdpCount++;
1979 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001980 }
1981 }
1982 }
radhakrishnac9a67412013-09-25 17:40:42 +05301983}
1984
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001985/*
1986 * Configures pipe(s) for MDP composition
1987 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001988int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001989 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001990 MdpPipeInfoNonSplit& mdp_info =
1991 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001992 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1993 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001994 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001995
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001996 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1997 __FUNCTION__, layer, zOrder, dest);
1998
Saurabh Shah2c8ad052014-08-15 13:27:46 -07001999 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002000 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002001}
2002
Saurabh Shah88e4d272013-09-03 13:31:29 -07002003bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002004 hwc_display_contents_1_t* list) {
2005 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002006
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002007 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002008
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002009 hwc_layer_1_t* layer = &list->hwLayers[index];
2010 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302011 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002012 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302013 continue;
2014 }
2015 }
2016
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002017 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002018 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002019 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002020 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002021 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002022
Saurabh Shahc62f3982014-03-05 14:28:26 -08002023 Overlay::PipeSpecs pipeSpecs;
2024 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2025 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2026 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2027 (qdutils::MDPVersion::getInstance().is8x26() and
2028 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2029 pipeSpecs.dpy = mDpy;
2030 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002031 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002032
Saurabh Shahc62f3982014-03-05 14:28:26 -08002033 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2034
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002035 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002036 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002037 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002038 }
2039 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002040 return true;
2041}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002042
radhakrishnac9a67412013-09-25 17:40:42 +05302043int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2044 PipeLayerPair& PipeLayerPair) {
2045 MdpYUVPipeInfo& mdp_info =
2046 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2047 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302048 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2049 eDest lDest = mdp_info.lIndex;
2050 eDest rDest = mdp_info.rIndex;
2051
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002052 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302053 lDest, rDest, &PipeLayerPair.rot);
2054}
2055
Saurabh Shah88e4d272013-09-03 13:31:29 -07002056bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002057
Raj Kamal4393eaa2014-06-06 13:45:20 +05302058 if(!isEnabled() or !mModeOn) {
2059 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302060 return true;
2061 }
2062
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002063 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002064 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002065 sHandleTimeout = true;
2066 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002067
2068 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002069 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002070
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002071 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2072 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002073 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002074 if(mCurrentFrame.isFBComposed[i]) continue;
2075
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002076 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002077 private_handle_t *hnd = (private_handle_t *)layer->handle;
2078 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002079 if (!(layer->flags & HWC_COLOR_FILL)) {
2080 ALOGE("%s handle null", __FUNCTION__);
2081 return false;
2082 }
2083 // No PLAY for Color layer
2084 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2085 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002086 }
2087
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002088 int mdpIndex = mCurrentFrame.layerToMDP[i];
2089
Raj Kamal389d6e32014-08-04 14:43:24 +05302090 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302091 {
2092 MdpYUVPipeInfo& pipe_info =
2093 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2094 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2095 ovutils::eDest indexL = pipe_info.lIndex;
2096 ovutils::eDest indexR = pipe_info.rIndex;
2097 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302098 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302099 if(rot) {
2100 rot->queueBuffer(fd, offset);
2101 fd = rot->getDstMemId();
2102 offset = rot->getDstOffset();
2103 }
2104 if(indexL != ovutils::OV_INVALID) {
2105 ovutils::eDest destL = (ovutils::eDest)indexL;
2106 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2107 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2108 if (!ov.queueBuffer(fd, offset, destL)) {
2109 ALOGE("%s: queueBuffer failed for display:%d",
2110 __FUNCTION__, mDpy);
2111 return false;
2112 }
2113 }
2114
2115 if(indexR != ovutils::OV_INVALID) {
2116 ovutils::eDest destR = (ovutils::eDest)indexR;
2117 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2118 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2119 if (!ov.queueBuffer(fd, offset, destR)) {
2120 ALOGE("%s: queueBuffer failed for display:%d",
2121 __FUNCTION__, mDpy);
2122 return false;
2123 }
2124 }
2125 }
2126 else{
2127 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002128 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302129 ovutils::eDest dest = pipe_info.index;
2130 if(dest == ovutils::OV_INVALID) {
2131 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002132 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302133 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002134
radhakrishnac9a67412013-09-25 17:40:42 +05302135 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2136 continue;
2137 }
2138
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002139 int fd = hnd->fd;
2140 uint32_t offset = (uint32_t)hnd->offset;
2141 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2142 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002143 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002144 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002145 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002146 }
2147
radhakrishnac9a67412013-09-25 17:40:42 +05302148 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2149 using pipe: %d", __FUNCTION__, layer,
2150 hnd, dest );
2151
radhakrishnac9a67412013-09-25 17:40:42 +05302152 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2153 if(rot) {
2154 if(!rot->queueBuffer(fd, offset))
2155 return false;
2156 fd = rot->getDstMemId();
2157 offset = rot->getDstOffset();
2158 }
2159
2160 if (!ov.queueBuffer(fd, offset, dest)) {
2161 ALOGE("%s: queueBuffer failed for display:%d ",
2162 __FUNCTION__, mDpy);
2163 return false;
2164 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002165 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002166
2167 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002168 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002169 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002170}
2171
Saurabh Shah88e4d272013-09-03 13:31:29 -07002172//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002173
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002174void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302175 hwc_display_contents_1_t* list){
2176 //if 4kx2k yuv layer is totally present in either in left half
2177 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302178 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302179 if(mCurrentFrame.fbZ >= 0) {
2180 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2181 index++) {
2182 if(!mCurrentFrame.isFBComposed[index]) {
2183 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2184 mdpNextZOrder++;
2185 }
2186 mdpNextZOrder++;
2187 hwc_layer_1_t* layer = &list->hwLayers[index];
2188 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302189 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302190 hwc_rect_t dst = layer->displayFrame;
2191 if((dst.left > lSplit) || (dst.right < lSplit)) {
2192 mCurrentFrame.mdpCount += 1;
2193 }
2194 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2195 mCurrentFrame.fbZ += 1;
2196 mdpNextZOrder++;
2197 }
2198 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002199 }
radhakrishnac9a67412013-09-25 17:40:42 +05302200 }
2201}
2202
Saurabh Shah88e4d272013-09-03 13:31:29 -07002203bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002204 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002205
Saurabh Shahc62f3982014-03-05 14:28:26 -08002206 const int lSplit = getLeftSplit(ctx, mDpy);
2207 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002208 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002209 pipe_info.lIndex = ovutils::OV_INVALID;
2210 pipe_info.rIndex = ovutils::OV_INVALID;
2211
Saurabh Shahc62f3982014-03-05 14:28:26 -08002212 Overlay::PipeSpecs pipeSpecs;
2213 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2214 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2215 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2216 pipeSpecs.dpy = mDpy;
2217 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2218 pipeSpecs.fb = false;
2219
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002220 // Acquire pipe only for the updating half
2221 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2222 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2223
2224 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002225 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002226 if(pipe_info.lIndex == ovutils::OV_INVALID)
2227 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002228 }
2229
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002230 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002231 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2232 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002233 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002234 return false;
2235 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002236
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002237 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002238}
2239
Saurabh Shah88e4d272013-09-03 13:31:29 -07002240bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002241 hwc_display_contents_1_t* list) {
2242 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002243
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002244 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002245
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002246 hwc_layer_1_t* layer = &list->hwLayers[index];
2247 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302248 hwc_rect_t dst = layer->displayFrame;
2249 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302250 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302251 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002252 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302253 continue;
2254 }
2255 }
2256 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002257 int mdpIndex = mCurrentFrame.layerToMDP[index];
2258 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002259 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002260 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002261 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002262
Saurabh Shahc62f3982014-03-05 14:28:26 -08002263 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2264 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2265 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002266 return false;
2267 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002268 }
2269 return true;
2270}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002271
radhakrishnac9a67412013-09-25 17:40:42 +05302272int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2273 PipeLayerPair& PipeLayerPair) {
2274 const int lSplit = getLeftSplit(ctx, mDpy);
2275 hwc_rect_t dst = layer->displayFrame;
2276 if((dst.left > lSplit)||(dst.right < lSplit)){
2277 MdpYUVPipeInfo& mdp_info =
2278 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2279 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302280 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2281 eDest lDest = mdp_info.lIndex;
2282 eDest rDest = mdp_info.rIndex;
2283
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002284 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302285 lDest, rDest, &PipeLayerPair.rot);
2286 }
2287 else{
2288 return configure(ctx, layer, PipeLayerPair);
2289 }
2290}
2291
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002292/*
2293 * Configures pipe(s) for MDP composition
2294 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002295int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002296 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002297 MdpPipeInfoSplit& mdp_info =
2298 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002299 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002300 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2301 eDest lDest = mdp_info.lIndex;
2302 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002303
2304 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2305 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2306
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002307 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002308 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002309}
2310
Saurabh Shah88e4d272013-09-03 13:31:29 -07002311bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002312
Raj Kamal4393eaa2014-06-06 13:45:20 +05302313 if(!isEnabled() or !mModeOn) {
2314 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302315 return true;
2316 }
2317
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002318 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002319 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002320 sHandleTimeout = true;
2321 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002322
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002323 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002324 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002325
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002326 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2327 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002328 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002329 if(mCurrentFrame.isFBComposed[i]) continue;
2330
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002331 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002332 private_handle_t *hnd = (private_handle_t *)layer->handle;
2333 if(!hnd) {
2334 ALOGE("%s handle null", __FUNCTION__);
2335 return false;
2336 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002337
2338 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2339 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002340 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002341
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002342 int mdpIndex = mCurrentFrame.layerToMDP[i];
2343
Raj Kamal389d6e32014-08-04 14:43:24 +05302344 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302345 {
2346 MdpYUVPipeInfo& pipe_info =
2347 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2348 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2349 ovutils::eDest indexL = pipe_info.lIndex;
2350 ovutils::eDest indexR = pipe_info.rIndex;
2351 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302352 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302353 if(rot) {
2354 rot->queueBuffer(fd, offset);
2355 fd = rot->getDstMemId();
2356 offset = rot->getDstOffset();
2357 }
2358 if(indexL != ovutils::OV_INVALID) {
2359 ovutils::eDest destL = (ovutils::eDest)indexL;
2360 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2361 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2362 if (!ov.queueBuffer(fd, offset, destL)) {
2363 ALOGE("%s: queueBuffer failed for display:%d",
2364 __FUNCTION__, mDpy);
2365 return false;
2366 }
2367 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002368
radhakrishnac9a67412013-09-25 17:40:42 +05302369 if(indexR != ovutils::OV_INVALID) {
2370 ovutils::eDest destR = (ovutils::eDest)indexR;
2371 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2372 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2373 if (!ov.queueBuffer(fd, offset, destR)) {
2374 ALOGE("%s: queueBuffer failed for display:%d",
2375 __FUNCTION__, mDpy);
2376 return false;
2377 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002378 }
2379 }
radhakrishnac9a67412013-09-25 17:40:42 +05302380 else{
2381 MdpPipeInfoSplit& pipe_info =
2382 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2383 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002384
radhakrishnac9a67412013-09-25 17:40:42 +05302385 ovutils::eDest indexL = pipe_info.lIndex;
2386 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002387
radhakrishnac9a67412013-09-25 17:40:42 +05302388 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002389 uint32_t offset = (uint32_t)hnd->offset;
2390 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2391 if (!mDpy && (index != -1)) {
2392 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2393 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002394 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002395 }
radhakrishnac9a67412013-09-25 17:40:42 +05302396
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002397 if(ctx->mAD->draw(ctx, fd, offset)) {
2398 fd = ctx->mAD->getDstFd();
2399 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002400 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002401
radhakrishnac9a67412013-09-25 17:40:42 +05302402 if(rot) {
2403 rot->queueBuffer(fd, offset);
2404 fd = rot->getDstMemId();
2405 offset = rot->getDstOffset();
2406 }
2407
2408 //************* play left mixer **********
2409 if(indexL != ovutils::OV_INVALID) {
2410 ovutils::eDest destL = (ovutils::eDest)indexL;
2411 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2412 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2413 if (!ov.queueBuffer(fd, offset, destL)) {
2414 ALOGE("%s: queueBuffer failed for left mixer",
2415 __FUNCTION__);
2416 return false;
2417 }
2418 }
2419
2420 //************* play right mixer **********
2421 if(indexR != ovutils::OV_INVALID) {
2422 ovutils::eDest destR = (ovutils::eDest)indexR;
2423 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2424 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2425 if (!ov.queueBuffer(fd, offset, destR)) {
2426 ALOGE("%s: queueBuffer failed for right mixer",
2427 __FUNCTION__);
2428 return false;
2429 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002430 }
2431 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002432
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002433 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2434 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002435
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002436 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002437}
Saurabh Shahab47c692014-02-12 18:45:57 -08002438
2439//================MDPCompSrcSplit==============================================
2440bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002441 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002442 private_handle_t *hnd = (private_handle_t *)layer->handle;
2443 hwc_rect_t dst = layer->displayFrame;
2444 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2445 pipe_info.lIndex = ovutils::OV_INVALID;
2446 pipe_info.rIndex = ovutils::OV_INVALID;
2447
2448 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2449 //should have a higher priority than the right one. Pipe priorities are
2450 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002451
Saurabh Shahc62f3982014-03-05 14:28:26 -08002452 Overlay::PipeSpecs pipeSpecs;
2453 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2454 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2455 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2456 pipeSpecs.dpy = mDpy;
2457 pipeSpecs.fb = false;
2458
Saurabh Shahab47c692014-02-12 18:45:57 -08002459 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002460 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002461 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002462 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002463 }
2464
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002465 /* Use 2 pipes IF
2466 a) Layer's crop width is > 2048 or
2467 b) Layer's dest width > 2048 or
2468 c) On primary, driver has indicated with caps to split always. This is
2469 based on an empirically derived value of panel height. Applied only
2470 if the layer's width is > mixer's width
2471 */
2472
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302473 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002474 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302475 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002476 int lSplit = getLeftSplit(ctx, mDpy);
2477 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002478 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2479 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002480
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002481 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2482 //pipe line length, we are still using 2 pipes. This is fine just because
2483 //this is source split where destination doesn't matter. Evaluate later to
2484 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002485 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2486 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002487 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002488 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002489 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002490 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002491 }
2492
2493 // Return values
2494 // 1 Left pipe is higher priority, do nothing.
2495 // 0 Pipes of same priority.
2496 //-1 Right pipe is of higher priority, needs swap.
2497 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2498 pipe_info.rIndex) == -1) {
2499 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002500 }
2501 }
2502
2503 return true;
2504}
2505
Saurabh Shahab47c692014-02-12 18:45:57 -08002506int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2507 PipeLayerPair& PipeLayerPair) {
2508 private_handle_t *hnd = (private_handle_t *)layer->handle;
2509 if(!hnd) {
2510 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2511 return -1;
2512 }
2513 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2514 MdpPipeInfoSplit& mdp_info =
2515 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2516 Rotator **rot = &PipeLayerPair.rot;
2517 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002518 eDest lDest = mdp_info.lIndex;
2519 eDest rDest = mdp_info.rIndex;
2520 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2521 hwc_rect_t dst = layer->displayFrame;
2522 int transform = layer->transform;
2523 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002524 int rotFlags = ROT_FLAGS_NONE;
2525 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2526 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2527
2528 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2529 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2530
2531 // Handle R/B swap
2532 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2533 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2534 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2535 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2536 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2537 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002538 /* Calculate the external display position based on MDP downscale,
2539 ActionSafe, and extorientation features. */
2540 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002541
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002542 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002543 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002544 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002545
2546 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2547 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002548 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002549 }
2550
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002551 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002552 (*rot) = ctx->mRotMgr->getNext();
2553 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002554 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002555 //If the video is using a single pipe, enable BWC
2556 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002557 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002558 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002559 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002560 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002561 ALOGE("%s: configRotator failed!", __FUNCTION__);
2562 return -1;
2563 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002564 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002565 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002566 }
2567
2568 //If 2 pipes being used, divide layer into half, crop and dst
2569 hwc_rect_t cropL = crop;
2570 hwc_rect_t cropR = crop;
2571 hwc_rect_t dstL = dst;
2572 hwc_rect_t dstR = dst;
2573 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2574 cropL.right = (crop.right + crop.left) / 2;
2575 cropR.left = cropL.right;
2576 sanitizeSourceCrop(cropL, cropR, hnd);
2577
Saurabh Shahb729b192014-08-15 18:04:24 -07002578 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002579 //Swap crops on H flip since 2 pipes are being used
2580 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2581 hwc_rect_t tmp = cropL;
2582 cropL = cropR;
2583 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002584 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002585 }
2586
Saurabh Shahb729b192014-08-15 18:04:24 -07002587 //cropSwap trick: If the src and dst widths are both odd, let us say
2588 //2507, then splitting both into half would cause left width to be 1253
2589 //and right 1254. If crop is swapped because of H flip, this will cause
2590 //left crop width to be 1254, whereas left dst width remains 1253, thus
2591 //inducing a scaling that is unaccounted for. To overcome that we add 1
2592 //to the dst width if there is a cropSwap. So if the original width was
2593 //2507, the left dst width will be 1254. Even if the original width was
2594 //even for ex: 2508, the left dst width will still remain 1254.
2595 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002596 dstR.left = dstL.right;
2597 }
2598
2599 //For the mdp, since either we are pre-rotating or MDP does flips
2600 orient = OVERLAY_TRANSFORM_0;
2601 transform = 0;
2602
2603 //configure left pipe
2604 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002605 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002606 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2607 (ovutils::eBlending) getBlending(layer->blending));
2608
2609 if(configMdp(ctx->mOverlay, pargL, orient,
2610 cropL, dstL, metadata, lDest) < 0) {
2611 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2612 return -1;
2613 }
2614 }
2615
2616 //configure right pipe
2617 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002618 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002619 static_cast<eRotFlags>(rotFlags),
2620 layer->planeAlpha,
2621 (ovutils::eBlending) getBlending(layer->blending));
2622 if(configMdp(ctx->mOverlay, pargR, orient,
2623 cropR, dstR, metadata, rDest) < 0) {
2624 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2625 return -1;
2626 }
2627 }
2628
2629 return 0;
2630}
2631
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002632}; //namespace
2633