blob: aca62f3dfe278a4370ecdc511f1089c4a3dc3366 [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
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400693 // No Idle fall back, if secure display or secure RGB layers are present or
694 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700695 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400696 !ctx->listStats[mDpy].secureRGBCount) &&
697 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700698 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
699 return false;
700 }
701
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800702 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700703 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
704 __FUNCTION__,
705 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800706 return false;
707 }
708
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700709 // if secondary is configuring or Padding round, fall back to video only
710 // composition and release all assigned non VIG pipes from primary.
711 if(isSecondaryConfiguring(ctx)) {
712 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
713 __FUNCTION__);
714 return false;
715 } else if(ctx->isPaddingRound) {
716 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
717 __FUNCTION__,mDpy);
718 return false;
719 }
720
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530721 MDPVersion& mdpHw = MDPVersion::getInstance();
722 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400723 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530724 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800725 // Disable MDP comp on Secondary when the primary is highres panel and
726 // the secondary is a normal 1080p, because, MDP comp on secondary under
727 // in such usecase, decimation gets used for downscale and there will be
728 // a quality mismatch when there will be a fallback to GPU comp
729 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
730 __FUNCTION__);
731 return false;
732 }
733
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700734 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800735 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700736 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800737 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
738 return false;
739 }
740
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800741 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800742 hwc_layer_1_t* layer = &list->hwLayers[i];
743 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800744
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800745 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700746 if(!canUseRotator(ctx, mDpy)) {
747 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
748 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700749 return false;
750 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800751 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530752
753 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
754 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700755 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530756 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
757 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
758 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800759 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700760
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700761 if(ctx->mAD->isDoable()) {
762 return false;
763 }
764
Saurabh Shahaa236822013-04-24 18:07:26 -0700765 //If all above hard conditions are met we can do full or partial MDP comp.
766 bool ret = false;
767 if(fullMDPComp(ctx, list)) {
768 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700769 } else if(fullMDPCompWithPTOR(ctx, list)) {
770 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700771 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700772 ret = true;
773 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530774
Saurabh Shahaa236822013-04-24 18:07:26 -0700775 return ret;
776}
777
778bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700779
780 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
781 return false;
782
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700783 //Will benefit presentation / secondary-only layer.
784 if((mDpy > HWC_DISPLAY_PRIMARY) &&
785 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
786 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
787 return false;
788 }
789
790 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
791 for(int i = 0; i < numAppLayers; i++) {
792 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700793 if(not mCurrentFrame.drop[i] and
794 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700795 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
796 return false;
797 }
798 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800799
Saurabh Shahaa236822013-04-24 18:07:26 -0700800 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700801 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
802 sizeof(mCurrentFrame.isFBComposed));
803 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
804 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700805
Raj Kamal389d6e32014-08-04 14:43:24 +0530806 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800807 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530808 }
809
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800810 if(!postHeuristicsHandling(ctx, list)) {
811 ALOGD_IF(isDebug(), "post heuristic handling failed");
812 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700813 return false;
814 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700815 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
816 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700817 return true;
818}
819
Sushil Chauhandefd3522014-05-13 18:17:12 -0700820/* Full MDP Composition with Peripheral Tiny Overlap Removal.
821 * MDP bandwidth limitations can be avoided, if the overlap region
822 * covered by the smallest layer at a higher z-order, gets composed
823 * by Copybit on a render buffer, which can be queued to MDP.
824 */
825bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
826 hwc_display_contents_1_t* list) {
827
828 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
829 const int stagesForMDP = min(sMaxPipesPerMixer,
830 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
831
832 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700833 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700834 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
835 return false;
836 }
837
838 // Frame level checks
839 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
840 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
841 isSecurePresent(ctx, mDpy)) {
842 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
843 return false;
844 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700845 // MDP comp checks
846 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700847 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700848 if(not isSupportedForMDPComp(ctx, layer)) {
849 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
850 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700851 }
852 }
853
Sushil Chauhandefd3522014-05-13 18:17:12 -0700854 /* We cannot use this composition mode, if:
855 1. A below layer needs scaling.
856 2. Overlap is not peripheral to display.
857 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700858 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700859 */
860
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700861 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
862 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
863 memset(overlapRect, 0, sizeof(overlapRect));
864 int layerPixelCount, minPixelCount = 0;
865 int numPTORLayersFound = 0;
866 for (int i = numAppLayers-1; (i >= 0 &&
867 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700868 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700869 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700870 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700871 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
872 // PTOR layer should be peripheral and cannot have transform
873 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
874 has90Transform(layer)) {
875 continue;
876 }
877 if((3 * (layerPixelCount + minPixelCount)) >
878 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
879 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
880 continue;
881 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700882 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700883 for (int j = i-1; j >= 0; j--) {
884 // Check if the layers below this layer qualifies for PTOR comp
885 hwc_layer_1_t* layer = &list->hwLayers[j];
886 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700887 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700889 if (isValidRect(getIntersection(dispFrame, disFrame))) {
890 if (has90Transform(layer) || needsScaling(layer)) {
891 found = false;
892 break;
893 }
894 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700895 }
896 }
897 // Store the minLayer Index
898 if(found) {
899 minLayerIndex[numPTORLayersFound] = i;
900 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
901 minPixelCount += layerPixelCount;
902 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 }
904 }
905
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 // No overlap layers
907 if (!numPTORLayersFound)
908 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700909
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 // Store the displayFrame and the sourceCrops of the layers
911 hwc_rect_t displayFrame[numAppLayers];
912 hwc_rect_t sourceCrop[numAppLayers];
913 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700914 hwc_layer_1_t* layer = &list->hwLayers[i];
915 displayFrame[i] = layer->displayFrame;
916 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700917 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700918
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530919 /**
920 * It's possible that 2 PTOR layers might have overlapping.
921 * In such case, remove the intersection(again if peripheral)
922 * from the lower PTOR layer to avoid overlapping.
923 * If intersection is not on peripheral then compromise
924 * by reducing number of PTOR layers.
925 **/
926 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
927 if(isValidRect(commonRect)) {
928 overlapRect[1] = deductRect(overlapRect[1], commonRect);
929 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
930 }
931
932 ctx->mPtorInfo.count = numPTORLayersFound;
933 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
934 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
935 }
936
937 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
938 // reset PTOR
939 ctx->mPtorInfo.count = 0;
940 if(isValidRect(commonRect)) {
941 // If PTORs are intersecting restore displayframe of PTOR[1]
942 // before returning, as we have modified it above.
943 list->hwLayers[minLayerIndex[1]].displayFrame =
944 displayFrame[minLayerIndex[1]];
945 }
946 return false;
947 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700948 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
949 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
950
Xu Yangcda012c2014-07-30 21:57:21 +0800951 // Store the blending mode, planeAlpha, and transform of PTOR layers
952 int32_t blending[numPTORLayersFound];
953 uint8_t planeAlpha[numPTORLayersFound];
954 uint32_t transform[numPTORLayersFound];
955
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 for(int j = 0; j < numPTORLayersFound; j++) {
957 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700958
959 // Update src crop of PTOR layer
960 hwc_layer_1_t* layer = &list->hwLayers[index];
961 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
962 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
963 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
964 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
965
966 // Store & update w, h, format of PTOR layer
967 private_handle_t *hnd = (private_handle_t *)layer->handle;
968 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
969 layerWhf[j] = whf;
970 hnd->width = renderBuf->width;
971 hnd->height = renderBuf->height;
972 hnd->format = renderBuf->format;
973
Xu Yangcda012c2014-07-30 21:57:21 +0800974 // Store & update blending mode, planeAlpha and transform of PTOR layer
975 blending[j] = layer->blending;
976 planeAlpha[j] = layer->planeAlpha;
977 transform[j] = layer->transform;
978 layer->blending = HWC_BLENDING_NONE;
979 layer->planeAlpha = 0xFF;
980 layer->transform = 0;
981
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700982 // Remove overlap from crop & displayFrame of below layers
983 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700984 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700985 if(!isValidRect(getIntersection(layer->displayFrame,
986 overlapRect[j]))) {
987 continue;
988 }
989 // Update layer attributes
990 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
991 hwc_rect_t destRect = deductRect(layer->displayFrame,
992 overlapRect[j]);
993 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
994 layer->transform);
995 layer->sourceCropf.left = (float)srcCrop.left;
996 layer->sourceCropf.top = (float)srcCrop.top;
997 layer->sourceCropf.right = (float)srcCrop.right;
998 layer->sourceCropf.bottom = (float)srcCrop.bottom;
999 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001000 }
1001
1002 mCurrentFrame.mdpCount = numAppLayers;
1003 mCurrentFrame.fbCount = 0;
1004 mCurrentFrame.fbZ = -1;
1005
1006 for (int j = 0; j < numAppLayers; j++)
1007 mCurrentFrame.isFBComposed[j] = false;
1008
1009 bool result = postHeuristicsHandling(ctx, list);
1010
1011 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001012 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001013 hwc_layer_1_t* layer = &list->hwLayers[i];
1014 layer->displayFrame = displayFrame[i];
1015 layer->sourceCropf.left = (float)sourceCrop[i].left;
1016 layer->sourceCropf.top = (float)sourceCrop[i].top;
1017 layer->sourceCropf.right = (float)sourceCrop[i].right;
1018 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1019 }
1020
Xu Yangcda012c2014-07-30 21:57:21 +08001021 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001022 for (int i = 0; i < numPTORLayersFound; i++) {
1023 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001024 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001025 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1026 hnd->width = layerWhf[i].w;
1027 hnd->height = layerWhf[i].h;
1028 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001029 layer->blending = blending[i];
1030 layer->planeAlpha = planeAlpha[i];
1031 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001032 }
1033
Sushil Chauhandefd3522014-05-13 18:17:12 -07001034 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001035 // reset PTOR
1036 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001037 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001038 } else {
1039 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1040 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001041 }
1042
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001043 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1044 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001045 return result;
1046}
1047
Saurabh Shahaa236822013-04-24 18:07:26 -07001048bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1049{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001050 if(!sEnableMixedMode) {
1051 //Mixed mode is disabled. No need to even try caching.
1052 return false;
1053 }
1054
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001055 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001056 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001057 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001058 cacheBasedComp(ctx, list);
1059 } else {
1060 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001061 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001062 }
1063
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001064 return ret;
1065}
1066
1067bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1068 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001069 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1070 return false;
1071
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001072 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001073 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001074 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001075
1076 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1077 for(int i = 0; i < numAppLayers; i++) {
1078 if(!mCurrentFrame.isFBComposed[i]) {
1079 hwc_layer_1_t* layer = &list->hwLayers[i];
1080 if(not isSupportedForMDPComp(ctx, layer)) {
1081 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1082 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001083 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001084 return false;
1085 }
1086 }
1087 }
1088
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001089 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001090 /* mark secure RGB layers for MDP comp */
1091 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301092 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001093 if(!ret) {
1094 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001095 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001096 return false;
1097 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001098
1099 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001100
Raj Kamal389d6e32014-08-04 14:43:24 +05301101 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001102 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301103 }
1104
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001105 //Will benefit cases where a video has non-updating background.
1106 if((mDpy > HWC_DISPLAY_PRIMARY) and
1107 (mdpCount > MAX_SEC_LAYERS)) {
1108 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001109 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001110 return false;
1111 }
1112
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001113 if(!postHeuristicsHandling(ctx, list)) {
1114 ALOGD_IF(isDebug(), "post heuristic handling failed");
1115 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001116 return false;
1117 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001118 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1119 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001120
Saurabh Shahaa236822013-04-24 18:07:26 -07001121 return true;
1122}
1123
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001124bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001125 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001126 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1127 return false;
1128
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001129 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001130 return false;
1131 }
1132
Saurabh Shahb772ae32013-11-18 15:40:02 -08001133 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001134 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1135 const int stagesForMDP = min(sMaxPipesPerMixer,
1136 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001137
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001138 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1139 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1140 int lastMDPSupportedIndex = numAppLayers;
1141 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001142
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001143 //Find the minimum MDP batch size
1144 for(int i = 0; i < numAppLayers;i++) {
1145 if(mCurrentFrame.drop[i]) {
1146 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001147 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001148 }
1149 hwc_layer_1_t* layer = &list->hwLayers[i];
1150 if(not isSupportedForMDPComp(ctx, layer)) {
1151 lastMDPSupportedIndex = i;
1152 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1153 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001154 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001155 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001156 }
1157
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001158 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1159 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1160 mCurrentFrame.dropCount);
1161
1162 //Start at a point where the fb batch should at least have 2 layers, for
1163 //this mode to be justified.
1164 while(fbBatchSize < 2) {
1165 ++fbBatchSize;
1166 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001167 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001168
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001169 //If there are no layers for MDP, this mode doesnt make sense.
1170 if(mdpBatchSize < 1) {
1171 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1172 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001173 return false;
1174 }
1175
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001176 mCurrentFrame.reset(numAppLayers);
1177
1178 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1179 while(mdpBatchSize > 0) {
1180 //Mark layers for MDP comp
1181 int mdpBatchLeft = mdpBatchSize;
1182 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1183 if(mCurrentFrame.drop[i]) {
1184 continue;
1185 }
1186 mCurrentFrame.isFBComposed[i] = false;
1187 --mdpBatchLeft;
1188 }
1189
1190 mCurrentFrame.fbZ = mdpBatchSize;
1191 mCurrentFrame.fbCount = fbBatchSize;
1192 mCurrentFrame.mdpCount = mdpBatchSize;
1193
1194 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1195 __FUNCTION__, mdpBatchSize, fbBatchSize,
1196 mCurrentFrame.dropCount);
1197
1198 if(postHeuristicsHandling(ctx, list)) {
1199 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001200 __FUNCTION__);
1201 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1202 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001203 return true;
1204 }
1205
1206 reset(ctx);
1207 --mdpBatchSize;
1208 ++fbBatchSize;
1209 }
1210
1211 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001212}
1213
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001214bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301215 if(mDpy or isSecurePresent(ctx, mDpy) or
1216 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001217 return false;
1218 }
1219 return true;
1220}
1221
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001222bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1223 hwc_display_contents_1_t* list){
1224 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1225 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1226 mDpy ) {
1227 return false;
1228 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001229 if(ctx->listStats[mDpy].secureUI)
1230 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001231 return true;
1232}
1233
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001234bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1235 hwc_display_contents_1_t* list) {
1236 const bool secureOnly = true;
1237 return videoOnlyComp(ctx, list, not secureOnly) or
1238 videoOnlyComp(ctx, list, secureOnly);
1239}
1240
1241bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001242 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001243 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1244 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001245 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001246
Saurabh Shahaa236822013-04-24 18:07:26 -07001247 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001248 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001249 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001250 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001251
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001252 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1253 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001254 return false;
1255 }
1256
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001257 /* Bail out if we are processing only secured video layers
1258 * and we dont have any */
1259 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001260 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001261 return false;
1262 }
1263
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001264 if(mCurrentFrame.fbCount)
1265 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001266
Raj Kamal389d6e32014-08-04 14:43:24 +05301267 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001268 adjustForSourceSplit(ctx, list);
1269 }
1270
1271 if(!postHeuristicsHandling(ctx, list)) {
1272 ALOGD_IF(isDebug(), "post heuristic handling failed");
1273 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001274 return false;
1275 }
1276
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001277 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1278 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001279 return true;
1280}
1281
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001282/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1283bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1284 hwc_display_contents_1_t* list) {
1285 const bool secureOnly = true;
1286 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1287 mdpOnlyLayersComp(ctx, list, secureOnly);
1288
1289}
1290
1291bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1292 hwc_display_contents_1_t* list, bool secureOnly) {
1293
1294 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1295 return false;
1296
1297 /* Bail out if we are processing only secured video layers
1298 * and we dont have any */
1299 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1300 reset(ctx);
1301 return false;
1302 }
1303
1304 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1305 mCurrentFrame.reset(numAppLayers);
1306 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1307
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001308 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001309 /* mark secure RGB layers for MDP comp */
1310 updateSecureRGB(ctx, list);
1311
1312 if(mCurrentFrame.mdpCount == 0) {
1313 reset(ctx);
1314 return false;
1315 }
1316
1317 /* find the maximum batch of layers to be marked for framebuffer */
1318 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1319 if(!ret) {
1320 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1321 reset(ctx);
1322 return false;
1323 }
1324
1325 if(sEnableYUVsplit){
1326 adjustForSourceSplit(ctx, list);
1327 }
1328
1329 if(!postHeuristicsHandling(ctx, list)) {
1330 ALOGD_IF(isDebug(), "post heuristic handling failed");
1331 reset(ctx);
1332 return false;
1333 }
1334
1335 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1336 __FUNCTION__);
1337 return true;
1338}
1339
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001340/* Checks for conditions where YUV layers cannot be bypassed */
1341bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001342 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001343 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001344 return false;
1345 }
1346
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001347 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001348 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1349 return false;
1350 }
1351
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001352 if(isSecuring(ctx, layer)) {
1353 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1354 return false;
1355 }
1356
Saurabh Shah4fdde762013-04-30 18:47:33 -07001357 if(!isValidDimension(ctx, layer)) {
1358 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1359 __FUNCTION__);
1360 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001361 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001362
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001363 if(layer->planeAlpha < 0xFF) {
1364 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1365 in video only mode",
1366 __FUNCTION__);
1367 return false;
1368 }
1369
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001370 return true;
1371}
1372
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001373/* Checks for conditions where Secure RGB layers cannot be bypassed */
1374bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1375 if(isSkipLayer(layer)) {
1376 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1377 __FUNCTION__, mDpy);
1378 return false;
1379 }
1380
1381 if(isSecuring(ctx, layer)) {
1382 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1383 return false;
1384 }
1385
1386 if(not isSupportedForMDPComp(ctx, layer)) {
1387 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1388 __FUNCTION__);
1389 return false;
1390 }
1391 return true;
1392}
1393
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301394/* starts at fromIndex and check for each layer to find
1395 * if it it has overlapping with any Updating layer above it in zorder
1396 * till the end of the batch. returns true if it finds any intersection */
1397bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1398 int fromIndex, int toIndex) {
1399 for(int i = fromIndex; i < toIndex; i++) {
1400 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1401 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1402 return false;
1403 }
1404 }
1405 }
1406 return true;
1407}
1408
1409/* Checks if given layer at targetLayerIndex has any
1410 * intersection with all the updating layers in beween
1411 * fromIndex and toIndex. Returns true if it finds intersectiion */
1412bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1413 int fromIndex, int toIndex, int targetLayerIndex) {
1414 for(int i = fromIndex; i <= toIndex; i++) {
1415 if(!mCurrentFrame.isFBComposed[i]) {
1416 if(areLayersIntersecting(&list->hwLayers[i],
1417 &list->hwLayers[targetLayerIndex])) {
1418 return true;
1419 }
1420 }
1421 }
1422 return false;
1423}
1424
1425int MDPComp::getBatch(hwc_display_contents_1_t* list,
1426 int& maxBatchStart, int& maxBatchEnd,
1427 int& maxBatchCount) {
1428 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301429 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001430 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301431 while (i < mCurrentFrame.layerCount) {
1432 int batchCount = 0;
1433 int batchStart = i;
1434 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001435 /* Adjust batch Z order with the dropped layers so far */
1436 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301437 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301438 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301439 while(i < mCurrentFrame.layerCount) {
1440 if(!mCurrentFrame.isFBComposed[i]) {
1441 if(!batchCount) {
1442 i++;
1443 break;
1444 }
1445 updatingLayersAbove++;
1446 i++;
1447 continue;
1448 } else {
1449 if(mCurrentFrame.drop[i]) {
1450 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001451 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301452 continue;
1453 } else if(updatingLayersAbove <= 0) {
1454 batchCount++;
1455 batchEnd = i;
1456 i++;
1457 continue;
1458 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1459
1460 // We have a valid updating layer already. If layer-i not
1461 // have overlapping with all updating layers in between
1462 // batch-start and i, then we can add layer i to batch.
1463 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1464 batchCount++;
1465 batchEnd = i;
1466 i++;
1467 continue;
1468 } else if(canPushBatchToTop(list, batchStart, i)) {
1469 //If All the non-updating layers with in this batch
1470 //does not have intersection with the updating layers
1471 //above in z-order, then we can safely move the batch to
1472 //higher z-order. Increment fbZ as it is moving up.
1473 if( firstZReverseIndex < 0) {
1474 firstZReverseIndex = i;
1475 }
1476 batchCount++;
1477 batchEnd = i;
1478 fbZ += updatingLayersAbove;
1479 i++;
1480 updatingLayersAbove = 0;
1481 continue;
1482 } else {
1483 //both failed.start the loop again from here.
1484 if(firstZReverseIndex >= 0) {
1485 i = firstZReverseIndex;
1486 }
1487 break;
1488 }
1489 }
1490 }
1491 }
1492 if(batchCount > maxBatchCount) {
1493 maxBatchCount = batchCount;
1494 maxBatchStart = batchStart;
1495 maxBatchEnd = batchEnd;
1496 fbZOrder = fbZ;
1497 }
1498 }
1499 return fbZOrder;
1500}
1501
1502bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1503 hwc_display_contents_1_t* list) {
1504 /* Idea is to keep as many non-updating(cached) layers in FB and
1505 * send rest of them through MDP. This is done in 2 steps.
1506 * 1. Find the maximum contiguous batch of non-updating layers.
1507 * 2. See if we can improve this batch size for caching by adding
1508 * opaque layers around the batch, if they don't have
1509 * any overlapping with the updating layers in between.
1510 * NEVER mark an updating layer for caching.
1511 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001512
1513 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001514 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001515 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301516 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001517
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001518 /* Nothing is cached. No batching needed */
1519 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001520 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001521 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001522
1523 /* No MDP comp layers, try to use other comp modes */
1524 if(mCurrentFrame.mdpCount == 0) {
1525 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001526 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001527
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001529
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301530 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001531 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001532 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001533 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301534 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001535 if(!mCurrentFrame.drop[i]){
1536 //If an unsupported layer is being attempted to
1537 //be pulled out we should fail
1538 if(not isSupportedForMDPComp(ctx, layer)) {
1539 return false;
1540 }
1541 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001542 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543 }
1544 }
1545
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301546 // update the frame data
1547 mCurrentFrame.fbZ = fbZ;
1548 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001549 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001550 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001551
1552 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301553 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001554
1555 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001556}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001557
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001558void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001559 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001560 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001561 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001562
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563 for(int i = 0; i < numAppLayers; i++) {
1564 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001565 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001566 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001567 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001568 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001569 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001570 }
1571 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001572
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001573 frame.fbCount = fbCount;
1574 frame.mdpCount = frame.layerCount - frame.fbCount
1575 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001576
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001577 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1578 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001579}
1580
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001581void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001582 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1584 for(int index = 0;index < nYuvCount; index++){
1585 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1586 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1587
1588 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001589 if(!frame.isFBComposed[nYuvIndex]) {
1590 frame.isFBComposed[nYuvIndex] = true;
1591 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001592 }
1593 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001594 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001595 private_handle_t *hnd = (private_handle_t *)layer->handle;
1596 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001597 frame.isFBComposed[nYuvIndex] = false;
1598 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001599 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001600 }
1601 }
1602 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001603
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001604 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1605 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606}
1607
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001608void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1609 hwc_display_contents_1_t* list) {
1610 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1611 for(int index = 0;index < nSecureRGBCount; index++){
1612 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1613 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1614
1615 if(!isSecureRGBDoable(ctx, layer)) {
1616 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1617 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1618 mCurrentFrame.fbCount++;
1619 }
1620 } else {
1621 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1622 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1623 mCurrentFrame.fbCount--;
1624 }
1625 }
1626 }
1627
1628 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1629 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1630 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1631 mCurrentFrame.fbCount);
1632}
1633
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001634hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1635 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001636 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001637
1638 /* Update only the region of FB needed for composition */
1639 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1640 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1641 hwc_layer_1_t* layer = &list->hwLayers[i];
1642 hwc_rect_t dst = layer->displayFrame;
1643 fbRect = getUnion(fbRect, dst);
1644 }
1645 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001646 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001647 return fbRect;
1648}
1649
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001650bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1651 hwc_display_contents_1_t* list) {
1652
1653 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001654 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001655 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1656 return false;
1657 }
1658
1659 //Limitations checks
1660 if(!hwLimitationsCheck(ctx, list)) {
1661 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1662 return false;
1663 }
1664
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001665 //Configure framebuffer first if applicable
1666 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001667 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001668 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1669 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001670 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1671 __FUNCTION__);
1672 return false;
1673 }
1674 }
1675
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001676 mCurrentFrame.map();
1677
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 if(!allocLayerPipes(ctx, list)) {
1679 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001680 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681 }
1682
1683 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001684 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001685 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686 int mdpIndex = mCurrentFrame.layerToMDP[index];
1687 hwc_layer_1_t* layer = &list->hwLayers[index];
1688
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301689 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1690 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1691 mdpNextZOrder++;
1692 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1694 cur_pipe->zOrder = mdpNextZOrder++;
1695
radhakrishnac9a67412013-09-25 17:40:42 +05301696 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301697 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301698 if(configure4k2kYuv(ctx, layer,
1699 mCurrentFrame.mdpToLayer[mdpIndex])
1700 != 0 ){
1701 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1702 for layer %d",__FUNCTION__, index);
1703 return false;
1704 }
1705 else{
1706 mdpNextZOrder++;
1707 }
1708 continue;
1709 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1711 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301712 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001713 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001714 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001715 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001716 }
1717
Saurabh Shaha36be922013-12-16 18:18:39 -08001718 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1719 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1720 ,__FUNCTION__, mDpy);
1721 return false;
1722 }
1723
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001724 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001725 return true;
1726}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001728bool MDPComp::resourceCheck(hwc_context_t* ctx,
1729 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001730 const bool fbUsed = mCurrentFrame.fbCount;
1731 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1732 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1733 return false;
1734 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001735 // Init rotCount to number of rotate sessions used by other displays
1736 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1737 // Count the number of rotator sessions required for current display
1738 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1739 if(!mCurrentFrame.isFBComposed[index]) {
1740 hwc_layer_1_t* layer = &list->hwLayers[index];
1741 private_handle_t *hnd = (private_handle_t *)layer->handle;
1742 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1743 rotCount++;
1744 }
1745 }
1746 }
1747 // if number of layers to rotate exceeds max rotator sessions, bail out.
1748 if(rotCount > RotMgr::MAX_ROT_SESS) {
1749 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1750 __FUNCTION__, mDpy);
1751 return false;
1752 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001753 return true;
1754}
1755
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301756bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1757 hwc_display_contents_1_t* list) {
1758
1759 //A-family hw limitation:
1760 //If a layer need alpha scaling, MDP can not support.
1761 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1762 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1763 if(!mCurrentFrame.isFBComposed[i] &&
1764 isAlphaScaled( &list->hwLayers[i])) {
1765 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1766 return false;
1767 }
1768 }
1769 }
1770
1771 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1772 //If multiple layers requires downscaling and also they are overlapping
1773 //fall back to GPU since MDSS can not handle it.
1774 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1775 qdutils::MDPVersion::getInstance().is8x26()) {
1776 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1777 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1778 if(!mCurrentFrame.isFBComposed[i] &&
1779 isDownscaleRequired(botLayer)) {
1780 //if layer-i is marked for MDP and needs downscaling
1781 //check if any MDP layer on top of i & overlaps with layer-i
1782 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1783 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1784 if(!mCurrentFrame.isFBComposed[j] &&
1785 isDownscaleRequired(topLayer)) {
1786 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1787 topLayer->displayFrame);
1788 if(isValidRect(r))
1789 return false;
1790 }
1791 }
1792 }
1793 }
1794 }
1795 return true;
1796}
1797
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001798int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001799 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001800 char property[PROPERTY_VALUE_MAX];
1801
Raj Kamal4393eaa2014-06-06 13:45:20 +05301802 if(!ctx || !list) {
1803 ALOGE("%s: Invalid context or list",__FUNCTION__);
1804 mCachedFrame.reset();
1805 return -1;
1806 }
1807
1808 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001809 if(mDpy == HWC_DISPLAY_PRIMARY) {
1810 sSimulationFlags = 0;
1811 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1812 int currentFlags = atoi(property);
1813 if(currentFlags != sSimulationFlags) {
1814 sSimulationFlags = currentFlags;
1815 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1816 sSimulationFlags, sSimulationFlags);
1817 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001818 }
1819 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001820 // reset PTOR
1821 if(!mDpy)
1822 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001823
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301824 //Do not cache the information for next draw cycle.
1825 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1826 ALOGI("%s: Unsupported layer count for mdp composition",
1827 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001828 mCachedFrame.reset();
1829 return -1;
1830 }
1831
Saurabh Shahb39f8152013-08-22 10:21:44 -07001832 //reset old data
1833 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001834 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1835 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301836
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001837 // Detect the start of animation and fall back to GPU only once to cache
1838 // all the layers in FB and display FB content untill animation completes.
1839 if(ctx->listStats[mDpy].isDisplayAnimating) {
1840 mCurrentFrame.needsRedraw = false;
1841 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1842 mCurrentFrame.needsRedraw = true;
1843 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1844 }
1845 setMDPCompLayerFlags(ctx, list);
1846 mCachedFrame.updateCounts(mCurrentFrame);
1847 ret = -1;
1848 return ret;
1849 } else {
1850 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1851 }
1852
Saurabh Shahb39f8152013-08-22 10:21:44 -07001853 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001854 if(isFrameDoable(ctx)) {
1855 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001856
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001857 // if tryFullFrame fails, try to push all video and secure RGB layers
1858 // to MDP for composition.
1859 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1860 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301861 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001862 setMDPCompLayerFlags(ctx, list);
1863 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001864 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001865 reset(ctx);
1866 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1867 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001868 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001869 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1870 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001871 }
1872 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001873 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1874 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001875 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001876 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001877
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001878 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001879 ALOGD("GEOMETRY change: %d",
1880 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001881 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001882 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001883 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001884 }
1885
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001886#ifdef DYNAMIC_FPS
1887 //For primary display, set the dynamic refreshrate
1888 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1889 FrameInfo frame;
1890 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301891 memset(&frame.drop, 0, sizeof(frame.drop));
1892 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001893 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1894 __FUNCTION__);
1895 updateLayerCache(ctx, list, frame);
1896 updateYUV(ctx, list, false /*secure only*/, frame);
1897 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1898 //Set the new fresh rate, if there is only one updating YUV layer
1899 //or there is one single RGB layer with this request
1900 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1901 (frame.layerCount == 1)) {
1902 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1903 }
1904 setRefreshRate(ctx, mDpy, refreshRate);
1905 }
1906#endif
1907
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001908 mCachedFrame.cacheAll(list);
1909 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001910 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001911}
1912
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001913bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301914
1915 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301916 int mdpIndex = mCurrentFrame.layerToMDP[index];
1917 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1918 info.pipeInfo = new MdpYUVPipeInfo;
1919 info.rot = NULL;
1920 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301921
1922 pipe_info.lIndex = ovutils::OV_INVALID;
1923 pipe_info.rIndex = ovutils::OV_INVALID;
1924
Saurabh Shahc62f3982014-03-05 14:28:26 -08001925 Overlay::PipeSpecs pipeSpecs;
1926 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1927 pipeSpecs.needsScaling = true;
1928 pipeSpecs.dpy = mDpy;
1929 pipeSpecs.fb = false;
1930
1931 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301932 if(pipe_info.lIndex == ovutils::OV_INVALID){
1933 bRet = false;
1934 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1935 __FUNCTION__);
1936 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001937 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301938 if(pipe_info.rIndex == ovutils::OV_INVALID){
1939 bRet = false;
1940 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1941 __FUNCTION__);
1942 }
1943 return bRet;
1944}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001945
1946int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1947 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001948 if (ctx->mPtorInfo.isActive()) {
1949 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001950 if (fd < 0) {
1951 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001952 }
1953 }
1954 return fd;
1955}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001956//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001957
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001958void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301959 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001960 //If 4k2k Yuv layer split is possible, and if
1961 //fbz is above 4k2k layer, increment fb zorder by 1
1962 //as we split 4k2k layer and increment zorder for right half
1963 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001964 if(!ctx)
1965 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001966 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301967 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1968 index++) {
1969 if(!mCurrentFrame.isFBComposed[index]) {
1970 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1971 mdpNextZOrder++;
1972 }
1973 mdpNextZOrder++;
1974 hwc_layer_1_t* layer = &list->hwLayers[index];
1975 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301976 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301977 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1978 mCurrentFrame.fbZ += 1;
1979 mdpNextZOrder++;
1980 //As we split 4kx2k yuv layer and program to 2 VG pipes
1981 //(if available) increase mdpcount by 1.
1982 mCurrentFrame.mdpCount++;
1983 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001984 }
1985 }
1986 }
radhakrishnac9a67412013-09-25 17:40:42 +05301987}
1988
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001989/*
1990 * Configures pipe(s) for MDP composition
1991 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001992int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001993 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001994 MdpPipeInfoNonSplit& mdp_info =
1995 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001996 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1997 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08001998 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001999
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002000 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2001 __FUNCTION__, layer, zOrder, dest);
2002
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002003 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002004 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002005}
2006
Saurabh Shah88e4d272013-09-03 13:31:29 -07002007bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002008 hwc_display_contents_1_t* list) {
2009 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002010
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002011 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002012
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002013 hwc_layer_1_t* layer = &list->hwLayers[index];
2014 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302015 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002016 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302017 continue;
2018 }
2019 }
2020
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002021 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002022 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002023 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002024 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002025 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002026
Saurabh Shahc62f3982014-03-05 14:28:26 -08002027 Overlay::PipeSpecs pipeSpecs;
2028 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2029 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2030 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2031 (qdutils::MDPVersion::getInstance().is8x26() and
2032 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2033 pipeSpecs.dpy = mDpy;
2034 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002035 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002036
Saurabh Shahc62f3982014-03-05 14:28:26 -08002037 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2038
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002039 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002040 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002041 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002042 }
2043 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002044 return true;
2045}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002046
radhakrishnac9a67412013-09-25 17:40:42 +05302047int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2048 PipeLayerPair& PipeLayerPair) {
2049 MdpYUVPipeInfo& mdp_info =
2050 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2051 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302052 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2053 eDest lDest = mdp_info.lIndex;
2054 eDest rDest = mdp_info.rIndex;
2055
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002056 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302057 lDest, rDest, &PipeLayerPair.rot);
2058}
2059
Saurabh Shah88e4d272013-09-03 13:31:29 -07002060bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002061
Raj Kamal4393eaa2014-06-06 13:45:20 +05302062 if(!isEnabled() or !mModeOn) {
2063 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302064 return true;
2065 }
2066
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002067 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002068 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002069 sHandleTimeout = true;
2070 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002071
2072 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002073 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002074
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002075 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2076 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002077 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002078 if(mCurrentFrame.isFBComposed[i]) continue;
2079
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002080 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002081 private_handle_t *hnd = (private_handle_t *)layer->handle;
2082 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002083 if (!(layer->flags & HWC_COLOR_FILL)) {
2084 ALOGE("%s handle null", __FUNCTION__);
2085 return false;
2086 }
2087 // No PLAY for Color layer
2088 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2089 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002090 }
2091
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002092 int mdpIndex = mCurrentFrame.layerToMDP[i];
2093
Raj Kamal389d6e32014-08-04 14:43:24 +05302094 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302095 {
2096 MdpYUVPipeInfo& pipe_info =
2097 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2098 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2099 ovutils::eDest indexL = pipe_info.lIndex;
2100 ovutils::eDest indexR = pipe_info.rIndex;
2101 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302102 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302103 if(rot) {
2104 rot->queueBuffer(fd, offset);
2105 fd = rot->getDstMemId();
2106 offset = rot->getDstOffset();
2107 }
2108 if(indexL != ovutils::OV_INVALID) {
2109 ovutils::eDest destL = (ovutils::eDest)indexL;
2110 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2111 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2112 if (!ov.queueBuffer(fd, offset, destL)) {
2113 ALOGE("%s: queueBuffer failed for display:%d",
2114 __FUNCTION__, mDpy);
2115 return false;
2116 }
2117 }
2118
2119 if(indexR != ovutils::OV_INVALID) {
2120 ovutils::eDest destR = (ovutils::eDest)indexR;
2121 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2122 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2123 if (!ov.queueBuffer(fd, offset, destR)) {
2124 ALOGE("%s: queueBuffer failed for display:%d",
2125 __FUNCTION__, mDpy);
2126 return false;
2127 }
2128 }
2129 }
2130 else{
2131 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002132 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302133 ovutils::eDest dest = pipe_info.index;
2134 if(dest == ovutils::OV_INVALID) {
2135 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002136 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302137 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002138
radhakrishnac9a67412013-09-25 17:40:42 +05302139 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2140 continue;
2141 }
2142
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002143 int fd = hnd->fd;
2144 uint32_t offset = (uint32_t)hnd->offset;
2145 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2146 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002147 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002148 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002149 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002150 }
2151
radhakrishnac9a67412013-09-25 17:40:42 +05302152 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2153 using pipe: %d", __FUNCTION__, layer,
2154 hnd, dest );
2155
radhakrishnac9a67412013-09-25 17:40:42 +05302156 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2157 if(rot) {
2158 if(!rot->queueBuffer(fd, offset))
2159 return false;
2160 fd = rot->getDstMemId();
2161 offset = rot->getDstOffset();
2162 }
2163
2164 if (!ov.queueBuffer(fd, offset, dest)) {
2165 ALOGE("%s: queueBuffer failed for display:%d ",
2166 __FUNCTION__, mDpy);
2167 return false;
2168 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002169 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002170
2171 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002172 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002173 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002174}
2175
Saurabh Shah88e4d272013-09-03 13:31:29 -07002176//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002177
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002178void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302179 hwc_display_contents_1_t* list){
2180 //if 4kx2k yuv layer is totally present in either in left half
2181 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302182 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302183 if(mCurrentFrame.fbZ >= 0) {
2184 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2185 index++) {
2186 if(!mCurrentFrame.isFBComposed[index]) {
2187 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2188 mdpNextZOrder++;
2189 }
2190 mdpNextZOrder++;
2191 hwc_layer_1_t* layer = &list->hwLayers[index];
2192 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302193 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302194 hwc_rect_t dst = layer->displayFrame;
2195 if((dst.left > lSplit) || (dst.right < lSplit)) {
2196 mCurrentFrame.mdpCount += 1;
2197 }
2198 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2199 mCurrentFrame.fbZ += 1;
2200 mdpNextZOrder++;
2201 }
2202 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002203 }
radhakrishnac9a67412013-09-25 17:40:42 +05302204 }
2205}
2206
Saurabh Shah88e4d272013-09-03 13:31:29 -07002207bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002208 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002209
Saurabh Shahc62f3982014-03-05 14:28:26 -08002210 const int lSplit = getLeftSplit(ctx, mDpy);
2211 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002212 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002213 pipe_info.lIndex = ovutils::OV_INVALID;
2214 pipe_info.rIndex = ovutils::OV_INVALID;
2215
Saurabh Shahc62f3982014-03-05 14:28:26 -08002216 Overlay::PipeSpecs pipeSpecs;
2217 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2218 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2219 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2220 pipeSpecs.dpy = mDpy;
2221 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2222 pipeSpecs.fb = false;
2223
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002224 // Acquire pipe only for the updating half
2225 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2226 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2227
2228 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002229 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002230 if(pipe_info.lIndex == ovutils::OV_INVALID)
2231 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002232 }
2233
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002234 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002235 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2236 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002237 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002238 return false;
2239 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002240
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002241 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002242}
2243
Saurabh Shah88e4d272013-09-03 13:31:29 -07002244bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002245 hwc_display_contents_1_t* list) {
2246 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002247
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002248 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002249
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002250 hwc_layer_1_t* layer = &list->hwLayers[index];
2251 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302252 hwc_rect_t dst = layer->displayFrame;
2253 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302254 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302255 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002256 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302257 continue;
2258 }
2259 }
2260 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002261 int mdpIndex = mCurrentFrame.layerToMDP[index];
2262 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002263 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002264 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002265 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002266
Saurabh Shahc62f3982014-03-05 14:28:26 -08002267 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2268 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2269 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002270 return false;
2271 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002272 }
2273 return true;
2274}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002275
radhakrishnac9a67412013-09-25 17:40:42 +05302276int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2277 PipeLayerPair& PipeLayerPair) {
2278 const int lSplit = getLeftSplit(ctx, mDpy);
2279 hwc_rect_t dst = layer->displayFrame;
2280 if((dst.left > lSplit)||(dst.right < lSplit)){
2281 MdpYUVPipeInfo& mdp_info =
2282 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2283 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302284 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2285 eDest lDest = mdp_info.lIndex;
2286 eDest rDest = mdp_info.rIndex;
2287
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002288 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302289 lDest, rDest, &PipeLayerPair.rot);
2290 }
2291 else{
2292 return configure(ctx, layer, PipeLayerPair);
2293 }
2294}
2295
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002296/*
2297 * Configures pipe(s) for MDP composition
2298 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002299int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002300 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002301 MdpPipeInfoSplit& mdp_info =
2302 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002303 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002304 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2305 eDest lDest = mdp_info.lIndex;
2306 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002307
2308 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2309 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2310
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002311 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002312 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002313}
2314
Saurabh Shah88e4d272013-09-03 13:31:29 -07002315bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002316
Raj Kamal4393eaa2014-06-06 13:45:20 +05302317 if(!isEnabled() or !mModeOn) {
2318 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302319 return true;
2320 }
2321
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002322 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002323 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002324 sHandleTimeout = true;
2325 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002326
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002327 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002328 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002329
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002330 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2331 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002332 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002333 if(mCurrentFrame.isFBComposed[i]) continue;
2334
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002335 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002336 private_handle_t *hnd = (private_handle_t *)layer->handle;
2337 if(!hnd) {
2338 ALOGE("%s handle null", __FUNCTION__);
2339 return false;
2340 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002341
2342 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2343 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002344 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002345
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002346 int mdpIndex = mCurrentFrame.layerToMDP[i];
2347
Raj Kamal389d6e32014-08-04 14:43:24 +05302348 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302349 {
2350 MdpYUVPipeInfo& pipe_info =
2351 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2352 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2353 ovutils::eDest indexL = pipe_info.lIndex;
2354 ovutils::eDest indexR = pipe_info.rIndex;
2355 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302356 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302357 if(rot) {
2358 rot->queueBuffer(fd, offset);
2359 fd = rot->getDstMemId();
2360 offset = rot->getDstOffset();
2361 }
2362 if(indexL != ovutils::OV_INVALID) {
2363 ovutils::eDest destL = (ovutils::eDest)indexL;
2364 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2365 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2366 if (!ov.queueBuffer(fd, offset, destL)) {
2367 ALOGE("%s: queueBuffer failed for display:%d",
2368 __FUNCTION__, mDpy);
2369 return false;
2370 }
2371 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002372
radhakrishnac9a67412013-09-25 17:40:42 +05302373 if(indexR != ovutils::OV_INVALID) {
2374 ovutils::eDest destR = (ovutils::eDest)indexR;
2375 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2376 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2377 if (!ov.queueBuffer(fd, offset, destR)) {
2378 ALOGE("%s: queueBuffer failed for display:%d",
2379 __FUNCTION__, mDpy);
2380 return false;
2381 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002382 }
2383 }
radhakrishnac9a67412013-09-25 17:40:42 +05302384 else{
2385 MdpPipeInfoSplit& pipe_info =
2386 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2387 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002388
radhakrishnac9a67412013-09-25 17:40:42 +05302389 ovutils::eDest indexL = pipe_info.lIndex;
2390 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002391
radhakrishnac9a67412013-09-25 17:40:42 +05302392 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002393 uint32_t offset = (uint32_t)hnd->offset;
2394 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2395 if (!mDpy && (index != -1)) {
2396 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2397 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002398 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002399 }
radhakrishnac9a67412013-09-25 17:40:42 +05302400
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002401 if(ctx->mAD->draw(ctx, fd, offset)) {
2402 fd = ctx->mAD->getDstFd();
2403 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002404 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002405
radhakrishnac9a67412013-09-25 17:40:42 +05302406 if(rot) {
2407 rot->queueBuffer(fd, offset);
2408 fd = rot->getDstMemId();
2409 offset = rot->getDstOffset();
2410 }
2411
2412 //************* play left mixer **********
2413 if(indexL != ovutils::OV_INVALID) {
2414 ovutils::eDest destL = (ovutils::eDest)indexL;
2415 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2416 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2417 if (!ov.queueBuffer(fd, offset, destL)) {
2418 ALOGE("%s: queueBuffer failed for left mixer",
2419 __FUNCTION__);
2420 return false;
2421 }
2422 }
2423
2424 //************* play right mixer **********
2425 if(indexR != ovutils::OV_INVALID) {
2426 ovutils::eDest destR = (ovutils::eDest)indexR;
2427 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2428 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2429 if (!ov.queueBuffer(fd, offset, destR)) {
2430 ALOGE("%s: queueBuffer failed for right mixer",
2431 __FUNCTION__);
2432 return false;
2433 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002434 }
2435 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002436
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002437 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2438 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002439
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002440 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002441}
Saurabh Shahab47c692014-02-12 18:45:57 -08002442
2443//================MDPCompSrcSplit==============================================
2444bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002445 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002446 private_handle_t *hnd = (private_handle_t *)layer->handle;
2447 hwc_rect_t dst = layer->displayFrame;
2448 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2449 pipe_info.lIndex = ovutils::OV_INVALID;
2450 pipe_info.rIndex = ovutils::OV_INVALID;
2451
2452 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2453 //should have a higher priority than the right one. Pipe priorities are
2454 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002455
Saurabh Shahc62f3982014-03-05 14:28:26 -08002456 Overlay::PipeSpecs pipeSpecs;
2457 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2458 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2459 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2460 pipeSpecs.dpy = mDpy;
2461 pipeSpecs.fb = false;
2462
Saurabh Shahab47c692014-02-12 18:45:57 -08002463 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002464 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002465 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002466 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002467 }
2468
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002469 /* Use 2 pipes IF
2470 a) Layer's crop width is > 2048 or
2471 b) Layer's dest width > 2048 or
2472 c) On primary, driver has indicated with caps to split always. This is
2473 based on an empirically derived value of panel height. Applied only
2474 if the layer's width is > mixer's width
2475 */
2476
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302477 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002478 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302479 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002480 int lSplit = getLeftSplit(ctx, mDpy);
2481 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002482 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2483 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002484
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002485 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2486 //pipe line length, we are still using 2 pipes. This is fine just because
2487 //this is source split where destination doesn't matter. Evaluate later to
2488 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002489 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2490 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002491 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002492 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002493 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002494 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002495 }
2496
2497 // Return values
2498 // 1 Left pipe is higher priority, do nothing.
2499 // 0 Pipes of same priority.
2500 //-1 Right pipe is of higher priority, needs swap.
2501 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2502 pipe_info.rIndex) == -1) {
2503 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002504 }
2505 }
2506
2507 return true;
2508}
2509
Saurabh Shahab47c692014-02-12 18:45:57 -08002510int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2511 PipeLayerPair& PipeLayerPair) {
2512 private_handle_t *hnd = (private_handle_t *)layer->handle;
2513 if(!hnd) {
2514 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2515 return -1;
2516 }
2517 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2518 MdpPipeInfoSplit& mdp_info =
2519 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2520 Rotator **rot = &PipeLayerPair.rot;
2521 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002522 eDest lDest = mdp_info.lIndex;
2523 eDest rDest = mdp_info.rIndex;
2524 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2525 hwc_rect_t dst = layer->displayFrame;
2526 int transform = layer->transform;
2527 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002528 int rotFlags = ROT_FLAGS_NONE;
2529 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2530 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2531
2532 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2533 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2534
2535 // Handle R/B swap
2536 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2537 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2538 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2539 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2540 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2541 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002542 /* Calculate the external display position based on MDP downscale,
2543 ActionSafe, and extorientation features. */
2544 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002545
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002546 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002547 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002548 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002549
2550 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2551 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002552 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002553 }
2554
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002555 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002556 (*rot) = ctx->mRotMgr->getNext();
2557 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002558 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002559 //If the video is using a single pipe, enable BWC
2560 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002561 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002562 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002563 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002564 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002565 ALOGE("%s: configRotator failed!", __FUNCTION__);
2566 return -1;
2567 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002568 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002569 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002570 }
2571
2572 //If 2 pipes being used, divide layer into half, crop and dst
2573 hwc_rect_t cropL = crop;
2574 hwc_rect_t cropR = crop;
2575 hwc_rect_t dstL = dst;
2576 hwc_rect_t dstR = dst;
2577 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2578 cropL.right = (crop.right + crop.left) / 2;
2579 cropR.left = cropL.right;
2580 sanitizeSourceCrop(cropL, cropR, hnd);
2581
Saurabh Shahb729b192014-08-15 18:04:24 -07002582 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002583 //Swap crops on H flip since 2 pipes are being used
2584 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2585 hwc_rect_t tmp = cropL;
2586 cropL = cropR;
2587 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002588 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002589 }
2590
Saurabh Shahb729b192014-08-15 18:04:24 -07002591 //cropSwap trick: If the src and dst widths are both odd, let us say
2592 //2507, then splitting both into half would cause left width to be 1253
2593 //and right 1254. If crop is swapped because of H flip, this will cause
2594 //left crop width to be 1254, whereas left dst width remains 1253, thus
2595 //inducing a scaling that is unaccounted for. To overcome that we add 1
2596 //to the dst width if there is a cropSwap. So if the original width was
2597 //2507, the left dst width will be 1254. Even if the original width was
2598 //even for ex: 2508, the left dst width will still remain 1254.
2599 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002600 dstR.left = dstL.right;
2601 }
2602
2603 //For the mdp, since either we are pre-rotating or MDP does flips
2604 orient = OVERLAY_TRANSFORM_0;
2605 transform = 0;
2606
2607 //configure left pipe
2608 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002609 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002610 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2611 (ovutils::eBlending) getBlending(layer->blending));
2612
2613 if(configMdp(ctx->mOverlay, pargL, orient,
2614 cropL, dstL, metadata, lDest) < 0) {
2615 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2616 return -1;
2617 }
2618 }
2619
2620 //configure right pipe
2621 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002622 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002623 static_cast<eRotFlags>(rotFlags),
2624 layer->planeAlpha,
2625 (ovutils::eBlending) getBlending(layer->blending));
2626 if(configMdp(ctx->mOverlay, pargR, orient,
2627 cropR, dstR, metadata, rDest) < 0) {
2628 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2629 return -1;
2630 }
2631 }
2632
2633 return 0;
2634}
2635
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002636}; //namespace
2637