blob: 5c913e6fd184458265148551d5d873aac8eda4ea [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;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053049bool MDPComp::enablePartialUpdateForMDP3 = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shah59562ff2014-09-30 16:13:12 -0700114 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700138 sIdleInvalidator = IdleInvalidator::getInstance();
139 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
140 delete sIdleInvalidator;
141 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400142 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800143 }
radhakrishnac9a67412013-09-25 17:40:42 +0530144
Saurabh Shah7c727642014-06-02 15:47:14 -0700145 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700146 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700147 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
148 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
149 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530150 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530151 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700152
153 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
154 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
155 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
156 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
157 HWC_DISPLAY_PRIMARY);
158 }
159
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530160 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
161 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
162 enablePartialUpdateForMDP3 = true;
163 }
164
165 if(!enablePartialUpdateForMDP3 &&
166 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
167 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
168 enablePartialUpdateForMDP3 = true;
169 }
170
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700171 return true;
172}
173
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800174void MDPComp::reset(hwc_context_t *ctx) {
175 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700176 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800177 ctx->mOverlay->clear(mDpy);
178 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700179}
180
Raj Kamal4393eaa2014-06-06 13:45:20 +0530181void MDPComp::reset() {
182 sHandleTimeout = false;
183 mModeOn = false;
184}
185
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700186void MDPComp::timeout_handler(void *udata) {
187 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
188
189 if(!ctx) {
190 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
191 return;
192 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800193 Locker::Autolock _l(ctx->mDrawLock);
194 // Handle timeout event only if the previous composition is MDP or MIXED.
195 if(!sHandleTimeout) {
196 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
197 return;
198 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700199 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700200 ALOGE("%s: HWC proc not registered", __FUNCTION__);
201 return;
202 }
203 sIdleFallBack = true;
204 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700205 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700206}
207
Saurabh Shah59562ff2014-09-30 16:13:12 -0700208void MDPComp::setIdleTimeout(const uint32_t& timeout) {
209 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
210
211 if(sIdleInvalidator) {
212 if(timeout <= ONE_REFRESH_PERIOD_MS) {
213 //If the specified timeout is < 1 draw cycle worth, "virtually"
214 //disable idle timeout. The ideal way for clients to disable
215 //timeout is to set it to 0
216 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
217 ALOGI("Disabled idle timeout");
218 return;
219 }
220 sIdleInvalidator->setIdleTimeout(timeout);
221 ALOGI("Idle timeout set to %u", timeout);
222 } else {
223 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
224 }
225}
226
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800227void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800228 hwc_display_contents_1_t* list) {
229 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800230
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800231 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800232 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800233 if(!mCurrentFrame.isFBComposed[index]) {
234 layerProp[index].mFlags |= HWC_MDPCOMP;
235 layer->compositionType = HWC_OVERLAY;
236 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800237 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700238 /* Drop the layer when its already present in FB OR when it lies
239 * outside frame's ROI */
240 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700242 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800243 }
244 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700245}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500246
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800247void MDPComp::setRedraw(hwc_context_t *ctx,
248 hwc_display_contents_1_t* list) {
249 mCurrentFrame.needsRedraw = false;
250 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
251 (list->flags & HWC_GEOMETRY_CHANGED) ||
252 isSkipPresent(ctx, mDpy)) {
253 mCurrentFrame.needsRedraw = true;
254 }
255}
256
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700258 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700259 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800261
Saurabh Shahaa236822013-04-24 18:07:26 -0700262void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700263 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264 if(mdpToLayer[i].pipeInfo) {
265 delete mdpToLayer[i].pipeInfo;
266 mdpToLayer[i].pipeInfo = NULL;
267 //We dont own the rotator
268 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800269 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800270 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800271
272 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
273 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700274 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800275
Saurabh Shahaa236822013-04-24 18:07:26 -0700276 layerCount = numLayers;
277 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800278 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700279 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800280 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800281}
282
Saurabh Shahaa236822013-04-24 18:07:26 -0700283void MDPComp::FrameInfo::map() {
284 // populate layer and MDP maps
285 int mdpIdx = 0;
286 for(int idx = 0; idx < layerCount; idx++) {
287 if(!isFBComposed[idx]) {
288 mdpToLayer[mdpIdx].listIndex = idx;
289 layerToMDP[idx] = mdpIdx++;
290 }
291 }
292}
293
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800294MDPComp::LayerCache::LayerCache() {
295 reset();
296}
297
298void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700299 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530300 memset(&isFBComposed, true, sizeof(isFBComposed));
301 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800302 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700303}
304
305void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530306 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700307 for(int i = 0; i < numAppLayers; i++) {
308 hnd[i] = list->hwLayers[i].handle;
309 }
310}
311
312void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700313 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530314 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
315 memcpy(&drop, &curFrame.drop, sizeof(drop));
316}
317
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800318bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
319 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530320 if(layerCount != curFrame.layerCount)
321 return false;
322 for(int i = 0; i < curFrame.layerCount; i++) {
323 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
324 (curFrame.drop[i] != drop[i])) {
325 return false;
326 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800327 if(curFrame.isFBComposed[i] &&
328 (hnd[i] != list->hwLayers[i].handle)){
329 return false;
330 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530331 }
332 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800333}
334
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700335bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
336 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800337 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700338 (not isValidDimension(ctx,layer))
339 //More conditions here, SKIP, sRGB+Blend etc
340 ) {
341 return false;
342 }
343 return true;
344}
345
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530346bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800347 private_handle_t *hnd = (private_handle_t *)layer->handle;
348
349 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700350 if (layer->flags & HWC_COLOR_FILL) {
351 // Color layer
352 return true;
353 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700354 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800355 return false;
356 }
357
Naseer Ahmede850a802013-09-06 13:12:52 -0400358 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400359 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400360 return false;
361
Saurabh Shah62e1d732013-09-17 10:44:05 -0700362 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700363 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700364 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700365 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
366 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700367 int dst_w = dst.right - dst.left;
368 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800369 float w_scale = ((float)crop_w / (float)dst_w);
370 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530371 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700372
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800373 /* Workaround for MDP HW limitation in DSI command mode panels where
374 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
375 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530376 * There also is a HW limilation in MDP, minimum block size is 2x2
377 * Fallback to GPU if height is less than 2.
378 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700379 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800380 return false;
381
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800382 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530383 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800384 const float w_dscale = w_scale;
385 const float h_dscale = h_scale;
386
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800387 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700388
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530389 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700390 /* On targets that doesnt support Decimation (eg.,8x26)
391 * maximum downscale support is overlay pipe downscale.
392 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400393 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530394 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700395 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800396 return false;
397 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700398 // Decimation on macrotile format layers is not supported.
399 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530400 /* Bail out if
401 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700402 * 2. exceeds maximum downscale limit
403 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400404 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530405 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700406 w_dscale > maxMDPDownscale ||
407 h_dscale > maxMDPDownscale) {
408 return false;
409 }
410 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800411 return false;
412 }
413 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700414 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700415 return false;
416 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700417 }
418
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800419 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530420 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800421 const float w_uscale = 1.0f / w_scale;
422 const float h_uscale = 1.0f / h_scale;
423
424 if(w_uscale > upscale || h_uscale > upscale)
425 return false;
426 }
427
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800428 return true;
429}
430
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800431bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700432 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800433
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800434 if(!isEnabled()) {
435 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530437 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530438 qdutils::MDPVersion::getInstance().is8x16() ||
439 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800440 ctx->mVideoTransFlag &&
441 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700442 //1 Padding round to shift pipes across mixers
443 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
444 __FUNCTION__);
445 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700446 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
447 /* TODO: freeing up all the resources only for the targets having total
448 number of pipes < 8. Need to analyze number of VIG pipes used
449 for primary in previous draw cycle and accordingly decide
450 whether to fall back to full GPU comp or video only comp
451 */
452 if(isSecondaryConfiguring(ctx)) {
453 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
454 __FUNCTION__);
455 ret = false;
456 } else if(ctx->isPaddingRound) {
457 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
458 __FUNCTION__,mDpy);
459 ret = false;
460 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700461 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700462 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800463}
464
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800465void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
466 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
467 fbRect = getIntersection(fbRect, roi);
468}
469
470/* 1) Identify layers that are not visible or lying outside the updating ROI and
471 * drop them from composition.
472 * 2) If we have a scaling layer which needs cropping against generated
473 * ROI, reset ROI to full resolution. */
474bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
475 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700476 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800477 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800478
479 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800480 if(!isValidRect(visibleRect)) {
481 mCurrentFrame.drop[i] = true;
482 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800483 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800484 }
485
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700486 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700487 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800488 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700489
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700490 if(!isValidRect(res)) {
491 mCurrentFrame.drop[i] = true;
492 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800493 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700494 /* Reset frame ROI when any layer which needs scaling also needs ROI
495 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800497 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
499 mCurrentFrame.dropCount = 0;
500 return false;
501 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800502
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800503 /* deduct any opaque region from visibleRect */
504 if (layer->blending == HWC_BLENDING_NONE)
505 visibleRect = deductRect(visibleRect, res);
506 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700507 }
508 return true;
509}
510
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800511/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
512 * are updating. If DirtyRegion is applicable, calculate it by accounting all
513 * the changing layer's dirtyRegion. */
514void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
515 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700516 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800517 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700518 return;
519
520 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800521 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
522 (int)ctx->dpyAttr[mDpy].yres};
523
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700524 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800525 hwc_layer_1_t* layer = &list->hwLayers[index];
526 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700528 hwc_rect_t dst = layer->displayFrame;
529 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800530
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800531#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800532 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700533 {
534 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
535 int x_off = dst.left - src.left;
536 int y_off = dst.top - src.top;
537 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
538 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800539#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800541 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700542 }
543 }
544
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800545 /* No layer is updating. Still SF wants a refresh.*/
546 if(!isValidRect(roi))
547 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800548
549 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800550 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800551
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800552 ctx->listStats[mDpy].lRoi = roi;
553 if(!validateAndApplyROI(ctx, list))
554 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700555
556 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800557 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
558 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
559}
560
561void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
562 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
563 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
564
565 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
566 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
567 fbRect = getUnion(l_fbRect, r_fbRect);
568}
569/* 1) Identify layers that are not visible or lying outside BOTH the updating
570 * ROI's and drop them from composition. If a layer is spanning across both
571 * the halves of the screen but needed by only ROI, the non-contributing
572 * half will not be programmed for MDP.
573 * 2) If we have a scaling layer which needs cropping against generated
574 * ROI, reset ROI to full resolution. */
575bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
576 hwc_display_contents_1_t* list) {
577
578 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
579
580 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
581 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
582
583 for(int i = numAppLayers - 1; i >= 0; i--){
584 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
585 {
586 mCurrentFrame.drop[i] = true;
587 mCurrentFrame.dropCount++;
588 continue;
589 }
590
591 const hwc_layer_1_t* layer = &list->hwLayers[i];
592 hwc_rect_t dstRect = layer->displayFrame;
593
594 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
595 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
596 hwc_rect_t res = getUnion(l_res, r_res);
597
598 if(!isValidRect(l_res) && !isValidRect(r_res)) {
599 mCurrentFrame.drop[i] = true;
600 mCurrentFrame.dropCount++;
601 } else {
602 /* Reset frame ROI when any layer which needs scaling also needs ROI
603 * cropping */
604 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
605 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
606 mCurrentFrame.dropCount = 0;
607 return false;
608 }
609
610 if (layer->blending == HWC_BLENDING_NONE) {
611 visibleRectL = deductRect(visibleRectL, l_res);
612 visibleRectR = deductRect(visibleRectR, r_res);
613 }
614 }
615 }
616 return true;
617}
618/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
619 * are updating. If DirtyRegion is applicable, calculate it by accounting all
620 * the changing layer's dirtyRegion. */
621void MDPCompSplit::generateROI(hwc_context_t *ctx,
622 hwc_display_contents_1_t* list) {
623 if(!canPartialUpdate(ctx, list))
624 return;
625
626 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
627 int lSplit = getLeftSplit(ctx, mDpy);
628
629 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
630 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
631
632 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
633 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
634
635 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
636 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
637
638 for(int index = 0; index < numAppLayers; index++ ) {
639 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800640 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800641 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800642 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700643 hwc_rect_t dst = layer->displayFrame;
644 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800645
646#ifdef QCOM_BSP
647 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700648 {
649 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
650 int x_off = dst.left - src.left;
651 int y_off = dst.top - src.top;
652 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
653 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800654#endif
655
656 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
657 if(isValidRect(l_dst))
658 l_roi = getUnion(l_roi, l_dst);
659
660 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
661 if(isValidRect(r_dst))
662 r_roi = getUnion(r_roi, r_dst);
663 }
664 }
665
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700666 /* For panels that cannot accept commands in both the interfaces, we cannot
667 * send two ROI's (for each half). We merge them into single ROI and split
668 * them across lSplit for MDP mixer use. The ROI's will be merged again
669 * finally before udpating the panel in the driver. */
670 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
671 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
672 l_roi = getIntersection(temp_roi, l_frame);
673 r_roi = getIntersection(temp_roi, r_frame);
674 }
675
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800676 /* No layer is updating. Still SF wants a refresh. */
677 if(!isValidRect(l_roi) && !isValidRect(r_roi))
678 return;
679
680 l_roi = getSanitizeROI(l_roi, l_frame);
681 r_roi = getSanitizeROI(r_roi, r_frame);
682
683 ctx->listStats[mDpy].lRoi = l_roi;
684 ctx->listStats[mDpy].rRoi = r_roi;
685
686 if(!validateAndApplyROI(ctx, list))
687 resetROI(ctx, mDpy);
688
689 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
690 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
691 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
692 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
693 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
694 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700695}
696
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800697/* Checks for conditions where all the layers marked for MDP comp cannot be
698 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800699bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800700 hwc_display_contents_1_t* list){
701
Saurabh Shahaa236822013-04-24 18:07:26 -0700702 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800703 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800704
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400705 // No Idle fall back, if secure display or secure RGB layers are present or
706 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700707 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400708 !ctx->listStats[mDpy].secureRGBCount) &&
709 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700710 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
711 return false;
712 }
713
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800714 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700715 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
716 __FUNCTION__,
717 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800718 return false;
719 }
720
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700721 // if secondary is configuring or Padding round, fall back to video only
722 // composition and release all assigned non VIG pipes from primary.
723 if(isSecondaryConfiguring(ctx)) {
724 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
725 __FUNCTION__);
726 return false;
727 } else if(ctx->isPaddingRound) {
728 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
729 __FUNCTION__,mDpy);
730 return false;
731 }
732
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530733 MDPVersion& mdpHw = MDPVersion::getInstance();
734 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400735 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530736 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800737 // Disable MDP comp on Secondary when the primary is highres panel and
738 // the secondary is a normal 1080p, because, MDP comp on secondary under
739 // in such usecase, decimation gets used for downscale and there will be
740 // a quality mismatch when there will be a fallback to GPU comp
741 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
742 __FUNCTION__);
743 return false;
744 }
745
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700746 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800747 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700748 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800749 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
750 return false;
751 }
752
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800753 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800754 hwc_layer_1_t* layer = &list->hwLayers[i];
755 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800756
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800757 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700758 if(!canUseRotator(ctx, mDpy)) {
759 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
760 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700761 return false;
762 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800763 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530764
765 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
766 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700767 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530768 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
769 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
770 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800771 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700772
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700773 if(ctx->mAD->isDoable()) {
774 return false;
775 }
776
Saurabh Shahaa236822013-04-24 18:07:26 -0700777 //If all above hard conditions are met we can do full or partial MDP comp.
778 bool ret = false;
779 if(fullMDPComp(ctx, list)) {
780 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700781 } else if(fullMDPCompWithPTOR(ctx, list)) {
782 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700783 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700784 ret = true;
785 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530786
Saurabh Shahaa236822013-04-24 18:07:26 -0700787 return ret;
788}
789
790bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700791
792 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
793 return false;
794
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700795 //Will benefit presentation / secondary-only layer.
796 if((mDpy > HWC_DISPLAY_PRIMARY) &&
797 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
798 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
799 return false;
800 }
801
802 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
803 for(int i = 0; i < numAppLayers; i++) {
804 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700805 if(not mCurrentFrame.drop[i] and
806 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700807 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
808 return false;
809 }
810 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800811
Saurabh Shahaa236822013-04-24 18:07:26 -0700812 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700813 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
814 sizeof(mCurrentFrame.isFBComposed));
815 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
816 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700817
Raj Kamal389d6e32014-08-04 14:43:24 +0530818 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800819 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530820 }
821
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800822 if(!postHeuristicsHandling(ctx, list)) {
823 ALOGD_IF(isDebug(), "post heuristic handling failed");
824 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700825 return false;
826 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700827 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
828 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700829 return true;
830}
831
Sushil Chauhandefd3522014-05-13 18:17:12 -0700832/* Full MDP Composition with Peripheral Tiny Overlap Removal.
833 * MDP bandwidth limitations can be avoided, if the overlap region
834 * covered by the smallest layer at a higher z-order, gets composed
835 * by Copybit on a render buffer, which can be queued to MDP.
836 */
837bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
838 hwc_display_contents_1_t* list) {
839
840 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
841 const int stagesForMDP = min(sMaxPipesPerMixer,
842 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
843
844 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700845 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700846 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
847 return false;
848 }
849
850 // Frame level checks
851 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
852 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
853 isSecurePresent(ctx, mDpy)) {
854 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
855 return false;
856 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700857 // MDP comp checks
858 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700859 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700860 if(not isSupportedForMDPComp(ctx, layer)) {
861 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
862 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700863 }
864 }
865
Sushil Chauhandefd3522014-05-13 18:17:12 -0700866 /* We cannot use this composition mode, if:
867 1. A below layer needs scaling.
868 2. Overlap is not peripheral to display.
869 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700870 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700871 */
872
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700873 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
874 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
875 memset(overlapRect, 0, sizeof(overlapRect));
876 int layerPixelCount, minPixelCount = 0;
877 int numPTORLayersFound = 0;
878 for (int i = numAppLayers-1; (i >= 0 &&
879 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700880 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700881 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700882 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700883 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
884 // PTOR layer should be peripheral and cannot have transform
885 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
886 has90Transform(layer)) {
887 continue;
888 }
889 if((3 * (layerPixelCount + minPixelCount)) >
890 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
891 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
892 continue;
893 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700894 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700895 for (int j = i-1; j >= 0; j--) {
896 // Check if the layers below this layer qualifies for PTOR comp
897 hwc_layer_1_t* layer = &list->hwLayers[j];
898 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700899 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700900 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700901 if (isValidRect(getIntersection(dispFrame, disFrame))) {
902 if (has90Transform(layer) || needsScaling(layer)) {
903 found = false;
904 break;
905 }
906 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700907 }
908 }
909 // Store the minLayer Index
910 if(found) {
911 minLayerIndex[numPTORLayersFound] = i;
912 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
913 minPixelCount += layerPixelCount;
914 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 }
916 }
917
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 // No overlap layers
919 if (!numPTORLayersFound)
920 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700921
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700922 // Store the displayFrame and the sourceCrops of the layers
923 hwc_rect_t displayFrame[numAppLayers];
924 hwc_rect_t sourceCrop[numAppLayers];
925 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700926 hwc_layer_1_t* layer = &list->hwLayers[i];
927 displayFrame[i] = layer->displayFrame;
928 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700929 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700930
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530931 /**
932 * It's possible that 2 PTOR layers might have overlapping.
933 * In such case, remove the intersection(again if peripheral)
934 * from the lower PTOR layer to avoid overlapping.
935 * If intersection is not on peripheral then compromise
936 * by reducing number of PTOR layers.
937 **/
938 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
939 if(isValidRect(commonRect)) {
940 overlapRect[1] = deductRect(overlapRect[1], commonRect);
941 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
942 }
943
944 ctx->mPtorInfo.count = numPTORLayersFound;
945 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
946 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
947 }
948
949 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
950 // reset PTOR
951 ctx->mPtorInfo.count = 0;
952 if(isValidRect(commonRect)) {
953 // If PTORs are intersecting restore displayframe of PTOR[1]
954 // before returning, as we have modified it above.
955 list->hwLayers[minLayerIndex[1]].displayFrame =
956 displayFrame[minLayerIndex[1]];
957 }
958 return false;
959 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700960 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
961 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
962
Xu Yangcda012c2014-07-30 21:57:21 +0800963 // Store the blending mode, planeAlpha, and transform of PTOR layers
964 int32_t blending[numPTORLayersFound];
965 uint8_t planeAlpha[numPTORLayersFound];
966 uint32_t transform[numPTORLayersFound];
967
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700968 for(int j = 0; j < numPTORLayersFound; j++) {
969 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700970
971 // Update src crop of PTOR layer
972 hwc_layer_1_t* layer = &list->hwLayers[index];
973 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
974 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
975 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
976 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
977
978 // Store & update w, h, format of PTOR layer
979 private_handle_t *hnd = (private_handle_t *)layer->handle;
980 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
981 layerWhf[j] = whf;
982 hnd->width = renderBuf->width;
983 hnd->height = renderBuf->height;
984 hnd->format = renderBuf->format;
985
Xu Yangcda012c2014-07-30 21:57:21 +0800986 // Store & update blending mode, planeAlpha and transform of PTOR layer
987 blending[j] = layer->blending;
988 planeAlpha[j] = layer->planeAlpha;
989 transform[j] = layer->transform;
990 layer->blending = HWC_BLENDING_NONE;
991 layer->planeAlpha = 0xFF;
992 layer->transform = 0;
993
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700994 // Remove overlap from crop & displayFrame of below layers
995 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700996 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700997 if(!isValidRect(getIntersection(layer->displayFrame,
998 overlapRect[j]))) {
999 continue;
1000 }
1001 // Update layer attributes
1002 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1003 hwc_rect_t destRect = deductRect(layer->displayFrame,
1004 overlapRect[j]);
1005 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1006 layer->transform);
1007 layer->sourceCropf.left = (float)srcCrop.left;
1008 layer->sourceCropf.top = (float)srcCrop.top;
1009 layer->sourceCropf.right = (float)srcCrop.right;
1010 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1011 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001012 }
1013
1014 mCurrentFrame.mdpCount = numAppLayers;
1015 mCurrentFrame.fbCount = 0;
1016 mCurrentFrame.fbZ = -1;
1017
1018 for (int j = 0; j < numAppLayers; j++)
1019 mCurrentFrame.isFBComposed[j] = false;
1020
1021 bool result = postHeuristicsHandling(ctx, list);
1022
1023 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001024 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001025 hwc_layer_1_t* layer = &list->hwLayers[i];
1026 layer->displayFrame = displayFrame[i];
1027 layer->sourceCropf.left = (float)sourceCrop[i].left;
1028 layer->sourceCropf.top = (float)sourceCrop[i].top;
1029 layer->sourceCropf.right = (float)sourceCrop[i].right;
1030 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1031 }
1032
Xu Yangcda012c2014-07-30 21:57:21 +08001033 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001034 for (int i = 0; i < numPTORLayersFound; i++) {
1035 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001036 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001037 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1038 hnd->width = layerWhf[i].w;
1039 hnd->height = layerWhf[i].h;
1040 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001041 layer->blending = blending[i];
1042 layer->planeAlpha = planeAlpha[i];
1043 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001044 }
1045
Sushil Chauhandefd3522014-05-13 18:17:12 -07001046 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001047 // reset PTOR
1048 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001049 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001050 } else {
1051 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1052 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001053 }
1054
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001055 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1056 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001057 return result;
1058}
1059
Saurabh Shahaa236822013-04-24 18:07:26 -07001060bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1061{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001062 if(!sEnableMixedMode) {
1063 //Mixed mode is disabled. No need to even try caching.
1064 return false;
1065 }
1066
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001067 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001068 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001069 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001070 cacheBasedComp(ctx, list);
1071 } else {
1072 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001073 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001074 }
1075
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001076 return ret;
1077}
1078
1079bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1080 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001081 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1082 return false;
1083
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001084 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001085 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001086 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001087
1088 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1089 for(int i = 0; i < numAppLayers; i++) {
1090 if(!mCurrentFrame.isFBComposed[i]) {
1091 hwc_layer_1_t* layer = &list->hwLayers[i];
1092 if(not isSupportedForMDPComp(ctx, layer)) {
1093 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1094 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001095 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001096 return false;
1097 }
1098 }
1099 }
1100
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001101 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001102 /* mark secure RGB layers for MDP comp */
1103 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301104 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001105 if(!ret) {
1106 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001107 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001108 return false;
1109 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001110
1111 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001112
Raj Kamal389d6e32014-08-04 14:43:24 +05301113 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001114 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301115 }
1116
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001117 //Will benefit cases where a video has non-updating background.
1118 if((mDpy > HWC_DISPLAY_PRIMARY) and
1119 (mdpCount > MAX_SEC_LAYERS)) {
1120 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001121 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001122 return false;
1123 }
1124
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001125 if(!postHeuristicsHandling(ctx, list)) {
1126 ALOGD_IF(isDebug(), "post heuristic handling failed");
1127 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001128 return false;
1129 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001130 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1131 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001132
Saurabh Shahaa236822013-04-24 18:07:26 -07001133 return true;
1134}
1135
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001136bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001137 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001138 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1139 return false;
1140
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001141 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001142 return false;
1143 }
1144
Saurabh Shahb772ae32013-11-18 15:40:02 -08001145 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001146 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1147 const int stagesForMDP = min(sMaxPipesPerMixer,
1148 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001149
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001150 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1151 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1152 int lastMDPSupportedIndex = numAppLayers;
1153 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001154
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001155 //Find the minimum MDP batch size
1156 for(int i = 0; i < numAppLayers;i++) {
1157 if(mCurrentFrame.drop[i]) {
1158 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001159 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001160 }
1161 hwc_layer_1_t* layer = &list->hwLayers[i];
1162 if(not isSupportedForMDPComp(ctx, layer)) {
1163 lastMDPSupportedIndex = i;
1164 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1165 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001166 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001167 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001168 }
1169
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001170 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1171 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1172 mCurrentFrame.dropCount);
1173
1174 //Start at a point where the fb batch should at least have 2 layers, for
1175 //this mode to be justified.
1176 while(fbBatchSize < 2) {
1177 ++fbBatchSize;
1178 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001179 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001180
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001181 //If there are no layers for MDP, this mode doesnt make sense.
1182 if(mdpBatchSize < 1) {
1183 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1184 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001185 return false;
1186 }
1187
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001188 mCurrentFrame.reset(numAppLayers);
1189
1190 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1191 while(mdpBatchSize > 0) {
1192 //Mark layers for MDP comp
1193 int mdpBatchLeft = mdpBatchSize;
1194 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1195 if(mCurrentFrame.drop[i]) {
1196 continue;
1197 }
1198 mCurrentFrame.isFBComposed[i] = false;
1199 --mdpBatchLeft;
1200 }
1201
1202 mCurrentFrame.fbZ = mdpBatchSize;
1203 mCurrentFrame.fbCount = fbBatchSize;
1204 mCurrentFrame.mdpCount = mdpBatchSize;
1205
1206 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1207 __FUNCTION__, mdpBatchSize, fbBatchSize,
1208 mCurrentFrame.dropCount);
1209
1210 if(postHeuristicsHandling(ctx, list)) {
1211 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001212 __FUNCTION__);
1213 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1214 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001215 return true;
1216 }
1217
1218 reset(ctx);
1219 --mdpBatchSize;
1220 ++fbBatchSize;
1221 }
1222
1223 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001224}
1225
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001226bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301227 if(mDpy or isSecurePresent(ctx, mDpy) or
1228 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001229 return false;
1230 }
1231 return true;
1232}
1233
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001234bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1235 hwc_display_contents_1_t* list){
1236 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1237 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1238 mDpy ) {
1239 return false;
1240 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001241 if(ctx->listStats[mDpy].secureUI)
1242 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001243 return true;
1244}
1245
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001246bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1247 hwc_display_contents_1_t* list) {
1248 const bool secureOnly = true;
1249 return videoOnlyComp(ctx, list, not secureOnly) or
1250 videoOnlyComp(ctx, list, secureOnly);
1251}
1252
1253bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001254 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001255 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1256 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001257 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001258
Saurabh Shahaa236822013-04-24 18:07:26 -07001259 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001260 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001261 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001262 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001263
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001264 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1265 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001266 return false;
1267 }
1268
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001269 /* Bail out if we are processing only secured video layers
1270 * and we dont have any */
1271 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001272 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001273 return false;
1274 }
1275
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001276 if(mCurrentFrame.fbCount)
1277 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001278
Raj Kamal389d6e32014-08-04 14:43:24 +05301279 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001280 adjustForSourceSplit(ctx, list);
1281 }
1282
1283 if(!postHeuristicsHandling(ctx, list)) {
1284 ALOGD_IF(isDebug(), "post heuristic handling failed");
1285 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001286 return false;
1287 }
1288
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001289 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1290 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001291 return true;
1292}
1293
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001294/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1295bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1296 hwc_display_contents_1_t* list) {
1297 const bool secureOnly = true;
1298 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1299 mdpOnlyLayersComp(ctx, list, secureOnly);
1300
1301}
1302
1303bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1304 hwc_display_contents_1_t* list, bool secureOnly) {
1305
1306 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1307 return false;
1308
1309 /* Bail out if we are processing only secured video layers
1310 * and we dont have any */
1311 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1312 reset(ctx);
1313 return false;
1314 }
1315
1316 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1317 mCurrentFrame.reset(numAppLayers);
1318 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1319
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001320 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001321 /* mark secure RGB layers for MDP comp */
1322 updateSecureRGB(ctx, list);
1323
1324 if(mCurrentFrame.mdpCount == 0) {
1325 reset(ctx);
1326 return false;
1327 }
1328
1329 /* find the maximum batch of layers to be marked for framebuffer */
1330 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1331 if(!ret) {
1332 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1333 reset(ctx);
1334 return false;
1335 }
1336
1337 if(sEnableYUVsplit){
1338 adjustForSourceSplit(ctx, list);
1339 }
1340
1341 if(!postHeuristicsHandling(ctx, list)) {
1342 ALOGD_IF(isDebug(), "post heuristic handling failed");
1343 reset(ctx);
1344 return false;
1345 }
1346
1347 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1348 __FUNCTION__);
1349 return true;
1350}
1351
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001352/* Checks for conditions where YUV layers cannot be bypassed */
1353bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001354 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001355 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001356 return false;
1357 }
1358
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001359 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001360 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1361 return false;
1362 }
1363
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001364 if(isSecuring(ctx, layer)) {
1365 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1366 return false;
1367 }
1368
Saurabh Shah4fdde762013-04-30 18:47:33 -07001369 if(!isValidDimension(ctx, layer)) {
1370 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1371 __FUNCTION__);
1372 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001373 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001374
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001375 if(layer->planeAlpha < 0xFF) {
1376 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1377 in video only mode",
1378 __FUNCTION__);
1379 return false;
1380 }
1381
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001382 return true;
1383}
1384
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001385/* Checks for conditions where Secure RGB layers cannot be bypassed */
1386bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1387 if(isSkipLayer(layer)) {
1388 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1389 __FUNCTION__, mDpy);
1390 return false;
1391 }
1392
1393 if(isSecuring(ctx, layer)) {
1394 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1395 return false;
1396 }
1397
1398 if(not isSupportedForMDPComp(ctx, layer)) {
1399 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1400 __FUNCTION__);
1401 return false;
1402 }
1403 return true;
1404}
1405
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301406/* starts at fromIndex and check for each layer to find
1407 * if it it has overlapping with any Updating layer above it in zorder
1408 * till the end of the batch. returns true if it finds any intersection */
1409bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1410 int fromIndex, int toIndex) {
1411 for(int i = fromIndex; i < toIndex; i++) {
1412 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1413 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1414 return false;
1415 }
1416 }
1417 }
1418 return true;
1419}
1420
1421/* Checks if given layer at targetLayerIndex has any
1422 * intersection with all the updating layers in beween
1423 * fromIndex and toIndex. Returns true if it finds intersectiion */
1424bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1425 int fromIndex, int toIndex, int targetLayerIndex) {
1426 for(int i = fromIndex; i <= toIndex; i++) {
1427 if(!mCurrentFrame.isFBComposed[i]) {
1428 if(areLayersIntersecting(&list->hwLayers[i],
1429 &list->hwLayers[targetLayerIndex])) {
1430 return true;
1431 }
1432 }
1433 }
1434 return false;
1435}
1436
1437int MDPComp::getBatch(hwc_display_contents_1_t* list,
1438 int& maxBatchStart, int& maxBatchEnd,
1439 int& maxBatchCount) {
1440 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301441 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001442 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301443 while (i < mCurrentFrame.layerCount) {
1444 int batchCount = 0;
1445 int batchStart = i;
1446 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001447 /* Adjust batch Z order with the dropped layers so far */
1448 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301449 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301450 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301451 while(i < mCurrentFrame.layerCount) {
1452 if(!mCurrentFrame.isFBComposed[i]) {
1453 if(!batchCount) {
1454 i++;
1455 break;
1456 }
1457 updatingLayersAbove++;
1458 i++;
1459 continue;
1460 } else {
1461 if(mCurrentFrame.drop[i]) {
1462 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001463 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301464 continue;
1465 } else if(updatingLayersAbove <= 0) {
1466 batchCount++;
1467 batchEnd = i;
1468 i++;
1469 continue;
1470 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1471
1472 // We have a valid updating layer already. If layer-i not
1473 // have overlapping with all updating layers in between
1474 // batch-start and i, then we can add layer i to batch.
1475 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1476 batchCount++;
1477 batchEnd = i;
1478 i++;
1479 continue;
1480 } else if(canPushBatchToTop(list, batchStart, i)) {
1481 //If All the non-updating layers with in this batch
1482 //does not have intersection with the updating layers
1483 //above in z-order, then we can safely move the batch to
1484 //higher z-order. Increment fbZ as it is moving up.
1485 if( firstZReverseIndex < 0) {
1486 firstZReverseIndex = i;
1487 }
1488 batchCount++;
1489 batchEnd = i;
1490 fbZ += updatingLayersAbove;
1491 i++;
1492 updatingLayersAbove = 0;
1493 continue;
1494 } else {
1495 //both failed.start the loop again from here.
1496 if(firstZReverseIndex >= 0) {
1497 i = firstZReverseIndex;
1498 }
1499 break;
1500 }
1501 }
1502 }
1503 }
1504 if(batchCount > maxBatchCount) {
1505 maxBatchCount = batchCount;
1506 maxBatchStart = batchStart;
1507 maxBatchEnd = batchEnd;
1508 fbZOrder = fbZ;
1509 }
1510 }
1511 return fbZOrder;
1512}
1513
1514bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1515 hwc_display_contents_1_t* list) {
1516 /* Idea is to keep as many non-updating(cached) layers in FB and
1517 * send rest of them through MDP. This is done in 2 steps.
1518 * 1. Find the maximum contiguous batch of non-updating layers.
1519 * 2. See if we can improve this batch size for caching by adding
1520 * opaque layers around the batch, if they don't have
1521 * any overlapping with the updating layers in between.
1522 * NEVER mark an updating layer for caching.
1523 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001524
1525 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001526 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001527 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001529
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001530 /* Nothing is cached. No batching needed */
1531 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001532 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001533 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001534
1535 /* No MDP comp layers, try to use other comp modes */
1536 if(mCurrentFrame.mdpCount == 0) {
1537 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001538 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001539
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301540 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001541
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301542 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001544 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001545 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301546 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001547 if(!mCurrentFrame.drop[i]){
1548 //If an unsupported layer is being attempted to
1549 //be pulled out we should fail
1550 if(not isSupportedForMDPComp(ctx, layer)) {
1551 return false;
1552 }
1553 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001554 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001555 }
1556 }
1557
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301558 // update the frame data
1559 mCurrentFrame.fbZ = fbZ;
1560 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001561 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001562 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563
1564 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301565 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001566
1567 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001568}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001569
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001570void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001571 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001572 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001573 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001574
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001575 for(int i = 0; i < numAppLayers; i++) {
1576 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001577 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001578 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001579 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001580 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001581 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001582 }
1583 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001584
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001585 frame.fbCount = fbCount;
1586 frame.mdpCount = frame.layerCount - frame.fbCount
1587 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001588
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001589 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1590 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001591}
1592
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001593void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001594 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001595 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1596 for(int index = 0;index < nYuvCount; index++){
1597 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1598 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1599
1600 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001601 if(!frame.isFBComposed[nYuvIndex]) {
1602 frame.isFBComposed[nYuvIndex] = true;
1603 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604 }
1605 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001606 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001607 private_handle_t *hnd = (private_handle_t *)layer->handle;
1608 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001609 frame.isFBComposed[nYuvIndex] = false;
1610 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001611 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612 }
1613 }
1614 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001615
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001616 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1617 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618}
1619
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001620void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1621 hwc_display_contents_1_t* list) {
1622 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1623 for(int index = 0;index < nSecureRGBCount; index++){
1624 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1625 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1626
1627 if(!isSecureRGBDoable(ctx, layer)) {
1628 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1629 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1630 mCurrentFrame.fbCount++;
1631 }
1632 } else {
1633 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1634 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1635 mCurrentFrame.fbCount--;
1636 }
1637 }
1638 }
1639
1640 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1641 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1642 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1643 mCurrentFrame.fbCount);
1644}
1645
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001646hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1647 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001648 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001649
1650 /* Update only the region of FB needed for composition */
1651 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1652 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1653 hwc_layer_1_t* layer = &list->hwLayers[i];
1654 hwc_rect_t dst = layer->displayFrame;
1655 fbRect = getUnion(fbRect, dst);
1656 }
1657 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001658 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001659 return fbRect;
1660}
1661
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001662bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1663 hwc_display_contents_1_t* list) {
1664
1665 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001666 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001667 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1668 return false;
1669 }
1670
1671 //Limitations checks
1672 if(!hwLimitationsCheck(ctx, list)) {
1673 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1674 return false;
1675 }
1676
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001677 //Configure framebuffer first if applicable
1678 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001679 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001680 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1681 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001682 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1683 __FUNCTION__);
1684 return false;
1685 }
1686 }
1687
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001688 mCurrentFrame.map();
1689
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001690 if(!allocLayerPipes(ctx, list)) {
1691 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001692 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693 }
1694
1695 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001696 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001697 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001698 int mdpIndex = mCurrentFrame.layerToMDP[index];
1699 hwc_layer_1_t* layer = &list->hwLayers[index];
1700
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301701 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1702 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1703 mdpNextZOrder++;
1704 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001705 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1706 cur_pipe->zOrder = mdpNextZOrder++;
1707
radhakrishnac9a67412013-09-25 17:40:42 +05301708 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301709 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301710 if(configure4k2kYuv(ctx, layer,
1711 mCurrentFrame.mdpToLayer[mdpIndex])
1712 != 0 ){
1713 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1714 for layer %d",__FUNCTION__, index);
1715 return false;
1716 }
1717 else{
1718 mdpNextZOrder++;
1719 }
1720 continue;
1721 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001722 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1723 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301724 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001725 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001726 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001727 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001728 }
1729
Saurabh Shaha36be922013-12-16 18:18:39 -08001730 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1731 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1732 ,__FUNCTION__, mDpy);
1733 return false;
1734 }
1735
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001736 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001737 return true;
1738}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001739
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001740bool MDPComp::resourceCheck(hwc_context_t* ctx,
1741 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001742 const bool fbUsed = mCurrentFrame.fbCount;
1743 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1744 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1745 return false;
1746 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001747 // Init rotCount to number of rotate sessions used by other displays
1748 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1749 // Count the number of rotator sessions required for current display
1750 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1751 if(!mCurrentFrame.isFBComposed[index]) {
1752 hwc_layer_1_t* layer = &list->hwLayers[index];
1753 private_handle_t *hnd = (private_handle_t *)layer->handle;
1754 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1755 rotCount++;
1756 }
1757 }
1758 }
1759 // if number of layers to rotate exceeds max rotator sessions, bail out.
1760 if(rotCount > RotMgr::MAX_ROT_SESS) {
1761 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1762 __FUNCTION__, mDpy);
1763 return false;
1764 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001765 return true;
1766}
1767
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301768bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1769 hwc_display_contents_1_t* list) {
1770
1771 //A-family hw limitation:
1772 //If a layer need alpha scaling, MDP can not support.
1773 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1774 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1775 if(!mCurrentFrame.isFBComposed[i] &&
1776 isAlphaScaled( &list->hwLayers[i])) {
1777 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1778 return false;
1779 }
1780 }
1781 }
1782
1783 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1784 //If multiple layers requires downscaling and also they are overlapping
1785 //fall back to GPU since MDSS can not handle it.
1786 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1787 qdutils::MDPVersion::getInstance().is8x26()) {
1788 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1789 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1790 if(!mCurrentFrame.isFBComposed[i] &&
1791 isDownscaleRequired(botLayer)) {
1792 //if layer-i is marked for MDP and needs downscaling
1793 //check if any MDP layer on top of i & overlaps with layer-i
1794 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1795 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1796 if(!mCurrentFrame.isFBComposed[j] &&
1797 isDownscaleRequired(topLayer)) {
1798 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1799 topLayer->displayFrame);
1800 if(isValidRect(r))
1801 return false;
1802 }
1803 }
1804 }
1805 }
1806 }
1807 return true;
1808}
1809
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001811 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001812 char property[PROPERTY_VALUE_MAX];
1813
Raj Kamal4393eaa2014-06-06 13:45:20 +05301814 if(!ctx || !list) {
1815 ALOGE("%s: Invalid context or list",__FUNCTION__);
1816 mCachedFrame.reset();
1817 return -1;
1818 }
1819
1820 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001821 if(mDpy == HWC_DISPLAY_PRIMARY) {
1822 sSimulationFlags = 0;
1823 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1824 int currentFlags = atoi(property);
1825 if(currentFlags != sSimulationFlags) {
1826 sSimulationFlags = currentFlags;
1827 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1828 sSimulationFlags, sSimulationFlags);
1829 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001830 }
1831 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001832 // reset PTOR
1833 if(!mDpy)
1834 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001835
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301836 //Do not cache the information for next draw cycle.
1837 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1838 ALOGI("%s: Unsupported layer count for mdp composition",
1839 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001840 mCachedFrame.reset();
1841 return -1;
1842 }
1843
Saurabh Shahb39f8152013-08-22 10:21:44 -07001844 //reset old data
1845 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001846 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1847 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301848
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001849 // Detect the start of animation and fall back to GPU only once to cache
1850 // all the layers in FB and display FB content untill animation completes.
1851 if(ctx->listStats[mDpy].isDisplayAnimating) {
1852 mCurrentFrame.needsRedraw = false;
1853 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1854 mCurrentFrame.needsRedraw = true;
1855 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1856 }
1857 setMDPCompLayerFlags(ctx, list);
1858 mCachedFrame.updateCounts(mCurrentFrame);
1859 ret = -1;
1860 return ret;
1861 } else {
1862 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1863 }
1864
Saurabh Shahb39f8152013-08-22 10:21:44 -07001865 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001866 if(isFrameDoable(ctx)) {
1867 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001868
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001869 // if tryFullFrame fails, try to push all video and secure RGB layers
1870 // to MDP for composition.
1871 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1872 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301873 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001874 setMDPCompLayerFlags(ctx, list);
1875 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001876 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001877 reset(ctx);
1878 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1879 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001880 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001881 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1882 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001883 }
1884 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301885 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1886 enablePartialUpdateForMDP3) {
1887 generateROI(ctx, list);
1888 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1889 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1890 }
1891 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001892 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1893 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001894 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001895 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001896
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001897 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001898 ALOGD("GEOMETRY change: %d",
1899 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001900 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001901 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001902 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001903 }
1904
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001905#ifdef DYNAMIC_FPS
1906 //For primary display, set the dynamic refreshrate
1907 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1908 FrameInfo frame;
1909 frame.reset(mCurrentFrame.layerCount);
1910 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1911 __FUNCTION__);
1912 updateLayerCache(ctx, list, frame);
1913 updateYUV(ctx, list, false /*secure only*/, frame);
1914 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1915 //Set the new fresh rate, if there is only one updating YUV layer
1916 //or there is one single RGB layer with this request
1917 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1918 (frame.layerCount == 1)) {
1919 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1920 }
1921 setRefreshRate(ctx, mDpy, refreshRate);
1922 }
1923#endif
1924
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001925 mCachedFrame.cacheAll(list);
1926 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001927 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001928}
1929
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001930bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301931
1932 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301933 int mdpIndex = mCurrentFrame.layerToMDP[index];
1934 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1935 info.pipeInfo = new MdpYUVPipeInfo;
1936 info.rot = NULL;
1937 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301938
1939 pipe_info.lIndex = ovutils::OV_INVALID;
1940 pipe_info.rIndex = ovutils::OV_INVALID;
1941
Saurabh Shahc62f3982014-03-05 14:28:26 -08001942 Overlay::PipeSpecs pipeSpecs;
1943 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1944 pipeSpecs.needsScaling = true;
1945 pipeSpecs.dpy = mDpy;
1946 pipeSpecs.fb = false;
1947
1948 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301949 if(pipe_info.lIndex == ovutils::OV_INVALID){
1950 bRet = false;
1951 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1952 __FUNCTION__);
1953 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001954 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301955 if(pipe_info.rIndex == ovutils::OV_INVALID){
1956 bRet = false;
1957 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1958 __FUNCTION__);
1959 }
1960 return bRet;
1961}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001962
1963int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1964 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001965 if (ctx->mPtorInfo.isActive()) {
1966 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001967 if (fd < 0) {
1968 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001969 }
1970 }
1971 return fd;
1972}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001973//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001974
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001975void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301976 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001977 //If 4k2k Yuv layer split is possible, and if
1978 //fbz is above 4k2k layer, increment fb zorder by 1
1979 //as we split 4k2k layer and increment zorder for right half
1980 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001981 if(!ctx)
1982 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001983 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301984 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1985 index++) {
1986 if(!mCurrentFrame.isFBComposed[index]) {
1987 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1988 mdpNextZOrder++;
1989 }
1990 mdpNextZOrder++;
1991 hwc_layer_1_t* layer = &list->hwLayers[index];
1992 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301993 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301994 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1995 mCurrentFrame.fbZ += 1;
1996 mdpNextZOrder++;
1997 //As we split 4kx2k yuv layer and program to 2 VG pipes
1998 //(if available) increase mdpcount by 1.
1999 mCurrentFrame.mdpCount++;
2000 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002001 }
2002 }
2003 }
radhakrishnac9a67412013-09-25 17:40:42 +05302004}
2005
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002006/*
2007 * Configures pipe(s) for MDP composition
2008 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002009int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002010 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002011 MdpPipeInfoNonSplit& mdp_info =
2012 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002013 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2014 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002015 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002016
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002017 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2018 __FUNCTION__, layer, zOrder, dest);
2019
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002020 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002021 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002022}
2023
Saurabh Shah88e4d272013-09-03 13:31:29 -07002024bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002025 hwc_display_contents_1_t* list) {
2026 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002027
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002028 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002029
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002030 hwc_layer_1_t* layer = &list->hwLayers[index];
2031 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302032 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002033 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302034 continue;
2035 }
2036 }
2037
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002038 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002039 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002040 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002041 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002042 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002043
Saurabh Shahc62f3982014-03-05 14:28:26 -08002044 Overlay::PipeSpecs pipeSpecs;
2045 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2046 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2047 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2048 (qdutils::MDPVersion::getInstance().is8x26() and
2049 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2050 pipeSpecs.dpy = mDpy;
2051 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002052 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002053
Saurabh Shahc62f3982014-03-05 14:28:26 -08002054 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2055
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002056 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002057 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002058 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002059 }
2060 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002061 return true;
2062}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002063
radhakrishnac9a67412013-09-25 17:40:42 +05302064int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2065 PipeLayerPair& PipeLayerPair) {
2066 MdpYUVPipeInfo& mdp_info =
2067 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2068 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302069 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2070 eDest lDest = mdp_info.lIndex;
2071 eDest rDest = mdp_info.rIndex;
2072
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002073 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302074 lDest, rDest, &PipeLayerPair.rot);
2075}
2076
Saurabh Shah88e4d272013-09-03 13:31:29 -07002077bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002078
Raj Kamal4393eaa2014-06-06 13:45:20 +05302079 if(!isEnabled() or !mModeOn) {
2080 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302081 return true;
2082 }
2083
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002084 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002085 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002086 sHandleTimeout = true;
2087 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002088
2089 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002090 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002091
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002092 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2093 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002094 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002095 if(mCurrentFrame.isFBComposed[i]) continue;
2096
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002097 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002098 private_handle_t *hnd = (private_handle_t *)layer->handle;
2099 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002100 if (!(layer->flags & HWC_COLOR_FILL)) {
2101 ALOGE("%s handle null", __FUNCTION__);
2102 return false;
2103 }
2104 // No PLAY for Color layer
2105 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2106 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002107 }
2108
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002109 int mdpIndex = mCurrentFrame.layerToMDP[i];
2110
Raj Kamal389d6e32014-08-04 14:43:24 +05302111 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302112 {
2113 MdpYUVPipeInfo& pipe_info =
2114 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2115 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2116 ovutils::eDest indexL = pipe_info.lIndex;
2117 ovutils::eDest indexR = pipe_info.rIndex;
2118 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302119 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302120 if(rot) {
2121 rot->queueBuffer(fd, offset);
2122 fd = rot->getDstMemId();
2123 offset = rot->getDstOffset();
2124 }
2125 if(indexL != ovutils::OV_INVALID) {
2126 ovutils::eDest destL = (ovutils::eDest)indexL;
2127 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2128 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2129 if (!ov.queueBuffer(fd, offset, destL)) {
2130 ALOGE("%s: queueBuffer failed for display:%d",
2131 __FUNCTION__, mDpy);
2132 return false;
2133 }
2134 }
2135
2136 if(indexR != ovutils::OV_INVALID) {
2137 ovutils::eDest destR = (ovutils::eDest)indexR;
2138 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2139 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2140 if (!ov.queueBuffer(fd, offset, destR)) {
2141 ALOGE("%s: queueBuffer failed for display:%d",
2142 __FUNCTION__, mDpy);
2143 return false;
2144 }
2145 }
2146 }
2147 else{
2148 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002149 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302150 ovutils::eDest dest = pipe_info.index;
2151 if(dest == ovutils::OV_INVALID) {
2152 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002153 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302154 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002155
radhakrishnac9a67412013-09-25 17:40:42 +05302156 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2157 continue;
2158 }
2159
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002160 int fd = hnd->fd;
2161 uint32_t offset = (uint32_t)hnd->offset;
2162 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2163 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002164 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002165 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002166 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002167 }
2168
radhakrishnac9a67412013-09-25 17:40:42 +05302169 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2170 using pipe: %d", __FUNCTION__, layer,
2171 hnd, dest );
2172
radhakrishnac9a67412013-09-25 17:40:42 +05302173 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2174 if(rot) {
2175 if(!rot->queueBuffer(fd, offset))
2176 return false;
2177 fd = rot->getDstMemId();
2178 offset = rot->getDstOffset();
2179 }
2180
2181 if (!ov.queueBuffer(fd, offset, dest)) {
2182 ALOGE("%s: queueBuffer failed for display:%d ",
2183 __FUNCTION__, mDpy);
2184 return false;
2185 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002186 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002187
2188 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002189 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002190 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002191}
2192
Saurabh Shah88e4d272013-09-03 13:31:29 -07002193//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002194
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002195void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302196 hwc_display_contents_1_t* list){
2197 //if 4kx2k yuv layer is totally present in either in left half
2198 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302199 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302200 if(mCurrentFrame.fbZ >= 0) {
2201 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2202 index++) {
2203 if(!mCurrentFrame.isFBComposed[index]) {
2204 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2205 mdpNextZOrder++;
2206 }
2207 mdpNextZOrder++;
2208 hwc_layer_1_t* layer = &list->hwLayers[index];
2209 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302210 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302211 hwc_rect_t dst = layer->displayFrame;
2212 if((dst.left > lSplit) || (dst.right < lSplit)) {
2213 mCurrentFrame.mdpCount += 1;
2214 }
2215 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2216 mCurrentFrame.fbZ += 1;
2217 mdpNextZOrder++;
2218 }
2219 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002220 }
radhakrishnac9a67412013-09-25 17:40:42 +05302221 }
2222}
2223
Saurabh Shah88e4d272013-09-03 13:31:29 -07002224bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002225 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002226
Saurabh Shahc62f3982014-03-05 14:28:26 -08002227 const int lSplit = getLeftSplit(ctx, mDpy);
2228 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002229 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002230 pipe_info.lIndex = ovutils::OV_INVALID;
2231 pipe_info.rIndex = ovutils::OV_INVALID;
2232
Saurabh Shahc62f3982014-03-05 14:28:26 -08002233 Overlay::PipeSpecs pipeSpecs;
2234 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2235 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2236 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2237 pipeSpecs.dpy = mDpy;
2238 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2239 pipeSpecs.fb = false;
2240
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002241 // Acquire pipe only for the updating half
2242 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2243 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2244
2245 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002246 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002247 if(pipe_info.lIndex == ovutils::OV_INVALID)
2248 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002249 }
2250
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002251 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002252 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2253 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002254 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002255 return false;
2256 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002257
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002258 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002259}
2260
Saurabh Shah88e4d272013-09-03 13:31:29 -07002261bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002262 hwc_display_contents_1_t* list) {
2263 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002264
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002265 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002266
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002267 hwc_layer_1_t* layer = &list->hwLayers[index];
2268 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302269 hwc_rect_t dst = layer->displayFrame;
2270 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302271 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302272 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002273 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302274 continue;
2275 }
2276 }
2277 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002278 int mdpIndex = mCurrentFrame.layerToMDP[index];
2279 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002280 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002281 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002282 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002283
Saurabh Shahc62f3982014-03-05 14:28:26 -08002284 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2285 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2286 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002287 return false;
2288 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002289 }
2290 return true;
2291}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002292
radhakrishnac9a67412013-09-25 17:40:42 +05302293int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2294 PipeLayerPair& PipeLayerPair) {
2295 const int lSplit = getLeftSplit(ctx, mDpy);
2296 hwc_rect_t dst = layer->displayFrame;
2297 if((dst.left > lSplit)||(dst.right < lSplit)){
2298 MdpYUVPipeInfo& mdp_info =
2299 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2300 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302301 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2302 eDest lDest = mdp_info.lIndex;
2303 eDest rDest = mdp_info.rIndex;
2304
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002305 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302306 lDest, rDest, &PipeLayerPair.rot);
2307 }
2308 else{
2309 return configure(ctx, layer, PipeLayerPair);
2310 }
2311}
2312
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002313/*
2314 * Configures pipe(s) for MDP composition
2315 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002316int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002317 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002318 MdpPipeInfoSplit& mdp_info =
2319 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002320 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002321 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2322 eDest lDest = mdp_info.lIndex;
2323 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002324
2325 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2326 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2327
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002328 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002329 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002330}
2331
Saurabh Shah88e4d272013-09-03 13:31:29 -07002332bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002333
Raj Kamal4393eaa2014-06-06 13:45:20 +05302334 if(!isEnabled() or !mModeOn) {
2335 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302336 return true;
2337 }
2338
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002339 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002340 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002341 sHandleTimeout = true;
2342 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002343
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002344 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002345 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002346
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002347 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2348 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002349 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002350 if(mCurrentFrame.isFBComposed[i]) continue;
2351
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002352 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002353 private_handle_t *hnd = (private_handle_t *)layer->handle;
2354 if(!hnd) {
2355 ALOGE("%s handle null", __FUNCTION__);
2356 return false;
2357 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002358
2359 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2360 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002361 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002362
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002363 int mdpIndex = mCurrentFrame.layerToMDP[i];
2364
Raj Kamal389d6e32014-08-04 14:43:24 +05302365 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302366 {
2367 MdpYUVPipeInfo& pipe_info =
2368 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2369 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2370 ovutils::eDest indexL = pipe_info.lIndex;
2371 ovutils::eDest indexR = pipe_info.rIndex;
2372 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302373 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302374 if(rot) {
2375 rot->queueBuffer(fd, offset);
2376 fd = rot->getDstMemId();
2377 offset = rot->getDstOffset();
2378 }
2379 if(indexL != ovutils::OV_INVALID) {
2380 ovutils::eDest destL = (ovutils::eDest)indexL;
2381 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2382 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2383 if (!ov.queueBuffer(fd, offset, destL)) {
2384 ALOGE("%s: queueBuffer failed for display:%d",
2385 __FUNCTION__, mDpy);
2386 return false;
2387 }
2388 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002389
radhakrishnac9a67412013-09-25 17:40:42 +05302390 if(indexR != ovutils::OV_INVALID) {
2391 ovutils::eDest destR = (ovutils::eDest)indexR;
2392 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2393 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2394 if (!ov.queueBuffer(fd, offset, destR)) {
2395 ALOGE("%s: queueBuffer failed for display:%d",
2396 __FUNCTION__, mDpy);
2397 return false;
2398 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002399 }
2400 }
radhakrishnac9a67412013-09-25 17:40:42 +05302401 else{
2402 MdpPipeInfoSplit& pipe_info =
2403 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2404 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002405
radhakrishnac9a67412013-09-25 17:40:42 +05302406 ovutils::eDest indexL = pipe_info.lIndex;
2407 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002408
radhakrishnac9a67412013-09-25 17:40:42 +05302409 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002410 uint32_t offset = (uint32_t)hnd->offset;
2411 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2412 if (!mDpy && (index != -1)) {
2413 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2414 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002415 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002416 }
radhakrishnac9a67412013-09-25 17:40:42 +05302417
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002418 if(ctx->mAD->draw(ctx, fd, offset)) {
2419 fd = ctx->mAD->getDstFd();
2420 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002421 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002422
radhakrishnac9a67412013-09-25 17:40:42 +05302423 if(rot) {
2424 rot->queueBuffer(fd, offset);
2425 fd = rot->getDstMemId();
2426 offset = rot->getDstOffset();
2427 }
2428
2429 //************* play left mixer **********
2430 if(indexL != ovutils::OV_INVALID) {
2431 ovutils::eDest destL = (ovutils::eDest)indexL;
2432 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2433 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2434 if (!ov.queueBuffer(fd, offset, destL)) {
2435 ALOGE("%s: queueBuffer failed for left mixer",
2436 __FUNCTION__);
2437 return false;
2438 }
2439 }
2440
2441 //************* play right mixer **********
2442 if(indexR != ovutils::OV_INVALID) {
2443 ovutils::eDest destR = (ovutils::eDest)indexR;
2444 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2445 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2446 if (!ov.queueBuffer(fd, offset, destR)) {
2447 ALOGE("%s: queueBuffer failed for right mixer",
2448 __FUNCTION__);
2449 return false;
2450 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002451 }
2452 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002453
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002454 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2455 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002456
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002457 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002458}
Saurabh Shahab47c692014-02-12 18:45:57 -08002459
2460//================MDPCompSrcSplit==============================================
2461bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002462 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002463 private_handle_t *hnd = (private_handle_t *)layer->handle;
2464 hwc_rect_t dst = layer->displayFrame;
2465 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2466 pipe_info.lIndex = ovutils::OV_INVALID;
2467 pipe_info.rIndex = ovutils::OV_INVALID;
2468
2469 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2470 //should have a higher priority than the right one. Pipe priorities are
2471 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002472
Saurabh Shahc62f3982014-03-05 14:28:26 -08002473 Overlay::PipeSpecs pipeSpecs;
2474 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2475 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2476 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2477 pipeSpecs.dpy = mDpy;
2478 pipeSpecs.fb = false;
2479
Saurabh Shahab47c692014-02-12 18:45:57 -08002480 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002481 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002482 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002483 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002484 }
2485
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002486 /* Use 2 pipes IF
2487 a) Layer's crop width is > 2048 or
2488 b) Layer's dest width > 2048 or
2489 c) On primary, driver has indicated with caps to split always. This is
2490 based on an empirically derived value of panel height. Applied only
2491 if the layer's width is > mixer's width
2492 */
2493
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302494 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002495 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302496 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002497 int lSplit = getLeftSplit(ctx, mDpy);
2498 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002499 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2500 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002501
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002502 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2503 //pipe line length, we are still using 2 pipes. This is fine just because
2504 //this is source split where destination doesn't matter. Evaluate later to
2505 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002506 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2507 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002508 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002509 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002510 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002511 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002512 }
2513
2514 // Return values
2515 // 1 Left pipe is higher priority, do nothing.
2516 // 0 Pipes of same priority.
2517 //-1 Right pipe is of higher priority, needs swap.
2518 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2519 pipe_info.rIndex) == -1) {
2520 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002521 }
2522 }
2523
2524 return true;
2525}
2526
Saurabh Shahab47c692014-02-12 18:45:57 -08002527int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2528 PipeLayerPair& PipeLayerPair) {
2529 private_handle_t *hnd = (private_handle_t *)layer->handle;
2530 if(!hnd) {
2531 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2532 return -1;
2533 }
2534 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2535 MdpPipeInfoSplit& mdp_info =
2536 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2537 Rotator **rot = &PipeLayerPair.rot;
2538 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002539 eDest lDest = mdp_info.lIndex;
2540 eDest rDest = mdp_info.rIndex;
2541 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2542 hwc_rect_t dst = layer->displayFrame;
2543 int transform = layer->transform;
2544 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002545 int rotFlags = ROT_FLAGS_NONE;
2546 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2547 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2548
2549 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2550 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2551
2552 // Handle R/B swap
2553 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2554 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2555 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2556 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2557 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2558 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002559 /* Calculate the external display position based on MDP downscale,
2560 ActionSafe, and extorientation features. */
2561 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002562
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002563 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002564 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002565 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002566
2567 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2568 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002569 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002570 }
2571
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002572 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002573 (*rot) = ctx->mRotMgr->getNext();
2574 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002575 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002576 //If the video is using a single pipe, enable BWC
2577 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002578 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002579 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002580 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002581 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002582 ALOGE("%s: configRotator failed!", __FUNCTION__);
2583 return -1;
2584 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002585 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002586 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002587 }
2588
2589 //If 2 pipes being used, divide layer into half, crop and dst
2590 hwc_rect_t cropL = crop;
2591 hwc_rect_t cropR = crop;
2592 hwc_rect_t dstL = dst;
2593 hwc_rect_t dstR = dst;
2594 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2595 cropL.right = (crop.right + crop.left) / 2;
2596 cropR.left = cropL.right;
2597 sanitizeSourceCrop(cropL, cropR, hnd);
2598
Saurabh Shahb729b192014-08-15 18:04:24 -07002599 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002600 //Swap crops on H flip since 2 pipes are being used
2601 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2602 hwc_rect_t tmp = cropL;
2603 cropL = cropR;
2604 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002605 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002606 }
2607
Saurabh Shahb729b192014-08-15 18:04:24 -07002608 //cropSwap trick: If the src and dst widths are both odd, let us say
2609 //2507, then splitting both into half would cause left width to be 1253
2610 //and right 1254. If crop is swapped because of H flip, this will cause
2611 //left crop width to be 1254, whereas left dst width remains 1253, thus
2612 //inducing a scaling that is unaccounted for. To overcome that we add 1
2613 //to the dst width if there is a cropSwap. So if the original width was
2614 //2507, the left dst width will be 1254. Even if the original width was
2615 //even for ex: 2508, the left dst width will still remain 1254.
2616 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002617 dstR.left = dstL.right;
2618 }
2619
2620 //For the mdp, since either we are pre-rotating or MDP does flips
2621 orient = OVERLAY_TRANSFORM_0;
2622 transform = 0;
2623
2624 //configure left pipe
2625 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002626 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002627 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2628 (ovutils::eBlending) getBlending(layer->blending));
2629
2630 if(configMdp(ctx->mOverlay, pargL, orient,
2631 cropL, dstL, metadata, lDest) < 0) {
2632 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2633 return -1;
2634 }
2635 }
2636
2637 //configure right pipe
2638 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002639 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002640 static_cast<eRotFlags>(rotFlags),
2641 layer->planeAlpha,
2642 (ovutils::eBlending) getBlending(layer->blending));
2643 if(configMdp(ctx->mOverlay, pargR, orient,
2644 cropR, dstR, metadata, rDest) < 0) {
2645 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2646 return -1;
2647 }
2648 }
2649
2650 return 0;
2651}
2652
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002653}; //namespace
2654