blob: e24925a8d55c63a7c4b2fde107db1f9cb2691180 [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
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530153 bool defaultPTOR = false;
154 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
155 //8x16 and 8x39 targets by default
156 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
157 (qdutils::MDPVersion::getInstance().is8x16() ||
158 qdutils::MDPVersion::getInstance().is8x39())) {
159 defaultPTOR = true;
160 }
161
162 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
163 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
165 HWC_DISPLAY_PRIMARY);
166 }
167
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530168 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
169 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
170 enablePartialUpdateForMDP3 = true;
171 }
172
173 if(!enablePartialUpdateForMDP3 &&
174 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
175 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
176 enablePartialUpdateForMDP3 = true;
177 }
178
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700179 return true;
180}
181
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800182void MDPComp::reset(hwc_context_t *ctx) {
183 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700184 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800185 ctx->mOverlay->clear(mDpy);
186 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700187}
188
Raj Kamal4393eaa2014-06-06 13:45:20 +0530189void MDPComp::reset() {
190 sHandleTimeout = false;
191 mModeOn = false;
192}
193
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700194void MDPComp::timeout_handler(void *udata) {
195 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
196
197 if(!ctx) {
198 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
199 return;
200 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800201 Locker::Autolock _l(ctx->mDrawLock);
202 // Handle timeout event only if the previous composition is MDP or MIXED.
203 if(!sHandleTimeout) {
204 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
205 return;
206 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700207 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700208 ALOGE("%s: HWC proc not registered", __FUNCTION__);
209 return;
210 }
211 sIdleFallBack = true;
212 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700213 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700214}
215
Saurabh Shah59562ff2014-09-30 16:13:12 -0700216void MDPComp::setIdleTimeout(const uint32_t& timeout) {
217 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
218
219 if(sIdleInvalidator) {
220 if(timeout <= ONE_REFRESH_PERIOD_MS) {
221 //If the specified timeout is < 1 draw cycle worth, "virtually"
222 //disable idle timeout. The ideal way for clients to disable
223 //timeout is to set it to 0
224 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
225 ALOGI("Disabled idle timeout");
226 return;
227 }
228 sIdleInvalidator->setIdleTimeout(timeout);
229 ALOGI("Idle timeout set to %u", timeout);
230 } else {
231 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
232 }
233}
234
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800235void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800236 hwc_display_contents_1_t* list) {
237 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800240 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241 if(!mCurrentFrame.isFBComposed[index]) {
242 layerProp[index].mFlags |= HWC_MDPCOMP;
243 layer->compositionType = HWC_OVERLAY;
244 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700246 /* Drop the layer when its already present in FB OR when it lies
247 * outside frame's ROI */
248 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800249 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700250 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800251 }
252 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700253}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500254
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800255void MDPComp::setRedraw(hwc_context_t *ctx,
256 hwc_display_contents_1_t* list) {
257 mCurrentFrame.needsRedraw = false;
258 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
259 (list->flags & HWC_GEOMETRY_CHANGED) ||
260 isSkipPresent(ctx, mDpy)) {
261 mCurrentFrame.needsRedraw = true;
262 }
263}
264
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800265MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700266 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700267 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800268}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800269
Saurabh Shahaa236822013-04-24 18:07:26 -0700270void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700271 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800272 if(mdpToLayer[i].pipeInfo) {
273 delete mdpToLayer[i].pipeInfo;
274 mdpToLayer[i].pipeInfo = NULL;
275 //We dont own the rotator
276 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800277 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800278 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800279
280 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
281 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700282 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283
Saurabh Shahaa236822013-04-24 18:07:26 -0700284 layerCount = numLayers;
285 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700287 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800288 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800289}
290
Saurabh Shahaa236822013-04-24 18:07:26 -0700291void MDPComp::FrameInfo::map() {
292 // populate layer and MDP maps
293 int mdpIdx = 0;
294 for(int idx = 0; idx < layerCount; idx++) {
295 if(!isFBComposed[idx]) {
296 mdpToLayer[mdpIdx].listIndex = idx;
297 layerToMDP[idx] = mdpIdx++;
298 }
299 }
300}
301
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800302MDPComp::LayerCache::LayerCache() {
303 reset();
304}
305
306void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700307 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530308 memset(&isFBComposed, true, sizeof(isFBComposed));
309 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800310 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700311}
312
313void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530314 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700315 for(int i = 0; i < numAppLayers; i++) {
316 hnd[i] = list->hwLayers[i].handle;
317 }
318}
319
320void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700321 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530322 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
323 memcpy(&drop, &curFrame.drop, sizeof(drop));
324}
325
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800326bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
327 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530328 if(layerCount != curFrame.layerCount)
329 return false;
330 for(int i = 0; i < curFrame.layerCount; i++) {
331 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
332 (curFrame.drop[i] != drop[i])) {
333 return false;
334 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800335 if(curFrame.isFBComposed[i] &&
336 (hnd[i] != list->hwLayers[i].handle)){
337 return false;
338 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530339 }
340 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800341}
342
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700343bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
344 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800345 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700346 (not isValidDimension(ctx,layer))
347 //More conditions here, SKIP, sRGB+Blend etc
348 ) {
349 return false;
350 }
351 return true;
352}
353
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530354bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800355 private_handle_t *hnd = (private_handle_t *)layer->handle;
356
357 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700358 if (layer->flags & HWC_COLOR_FILL) {
359 // Color layer
360 return true;
361 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700362 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800363 return false;
364 }
365
Naseer Ahmede850a802013-09-06 13:12:52 -0400366 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400367 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400368 return false;
369
Saurabh Shah62e1d732013-09-17 10:44:05 -0700370 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700371 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700372 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700373 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
374 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700375 int dst_w = dst.right - dst.left;
376 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800377 float w_scale = ((float)crop_w / (float)dst_w);
378 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530379 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700380
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800381 /* Workaround for MDP HW limitation in DSI command mode panels where
382 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
383 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530384 * There also is a HW limilation in MDP, minimum block size is 2x2
385 * Fallback to GPU if height is less than 2.
386 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700387 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800388 return false;
389
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800390 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530391 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800392 const float w_dscale = w_scale;
393 const float h_dscale = h_scale;
394
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800395 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530397 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700398 /* On targets that doesnt support Decimation (eg.,8x26)
399 * maximum downscale support is overlay pipe downscale.
400 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400401 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530402 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700403 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800404 return false;
405 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700406 // Decimation on macrotile format layers is not supported.
407 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530408 /* Bail out if
409 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700410 * 2. exceeds maximum downscale limit
411 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400412 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530413 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700414 w_dscale > maxMDPDownscale ||
415 h_dscale > maxMDPDownscale) {
416 return false;
417 }
418 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800419 return false;
420 }
421 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700422 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700423 return false;
424 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700425 }
426
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800427 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530428 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800429 const float w_uscale = 1.0f / w_scale;
430 const float h_uscale = 1.0f / h_scale;
431
432 if(w_uscale > upscale || h_uscale > upscale)
433 return false;
434 }
435
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800436 return true;
437}
438
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800439bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700440 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800441
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800442 if(!isEnabled()) {
443 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700444 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530445 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530446 qdutils::MDPVersion::getInstance().is8x16() ||
447 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800448 ctx->mVideoTransFlag &&
449 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700450 //1 Padding round to shift pipes across mixers
451 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
452 __FUNCTION__);
453 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700454 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
455 /* TODO: freeing up all the resources only for the targets having total
456 number of pipes < 8. Need to analyze number of VIG pipes used
457 for primary in previous draw cycle and accordingly decide
458 whether to fall back to full GPU comp or video only comp
459 */
460 if(isSecondaryConfiguring(ctx)) {
461 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
462 __FUNCTION__);
463 ret = false;
464 } else if(ctx->isPaddingRound) {
465 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
466 __FUNCTION__,mDpy);
467 ret = false;
468 }
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700469 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700470 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800471}
472
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800473void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
474 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
475 fbRect = getIntersection(fbRect, roi);
476}
477
478/* 1) Identify layers that are not visible or lying outside the updating ROI and
479 * drop them from composition.
480 * 2) If we have a scaling layer which needs cropping against generated
481 * ROI, reset ROI to full resolution. */
482bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
483 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700484 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800485 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800486
487 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800488 if(!isValidRect(visibleRect)) {
489 mCurrentFrame.drop[i] = true;
490 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800491 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800492 }
493
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700494 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700495 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800496 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700497
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 if(!isValidRect(res)) {
499 mCurrentFrame.drop[i] = true;
500 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800501 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700502 /* Reset frame ROI when any layer which needs scaling also needs ROI
503 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800504 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800505 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700506 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
507 mCurrentFrame.dropCount = 0;
508 return false;
509 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800510
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800511 /* deduct any opaque region from visibleRect */
512 if (layer->blending == HWC_BLENDING_NONE)
513 visibleRect = deductRect(visibleRect, res);
514 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700515 }
516 return true;
517}
518
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
520 * are updating. If DirtyRegion is applicable, calculate it by accounting all
521 * the changing layer's dirtyRegion. */
522void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
523 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700524 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800525 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700526 return;
527
528 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800529 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
530 (int)ctx->dpyAttr[mDpy].yres};
531
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700532 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800533 hwc_layer_1_t* layer = &list->hwLayers[index];
534 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700536 hwc_rect_t dst = layer->displayFrame;
537 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800538
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800539#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700541 {
542 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
543 int x_off = dst.left - src.left;
544 int y_off = dst.top - src.top;
545 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
546 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800547#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800548
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800549 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550 }
551 }
552
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800553 /* No layer is updating. Still SF wants a refresh.*/
554 if(!isValidRect(roi))
555 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800556
557 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800558 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800559
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800560 ctx->listStats[mDpy].lRoi = roi;
561 if(!validateAndApplyROI(ctx, list))
562 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700563
564 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800565 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
566 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
567}
568
569void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
570 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
571 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
572
573 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
574 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
575 fbRect = getUnion(l_fbRect, r_fbRect);
576}
577/* 1) Identify layers that are not visible or lying outside BOTH the updating
578 * ROI's and drop them from composition. If a layer is spanning across both
579 * the halves of the screen but needed by only ROI, the non-contributing
580 * half will not be programmed for MDP.
581 * 2) If we have a scaling layer which needs cropping against generated
582 * ROI, reset ROI to full resolution. */
583bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
584 hwc_display_contents_1_t* list) {
585
586 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
587
588 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
589 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
590
591 for(int i = numAppLayers - 1; i >= 0; i--){
592 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
593 {
594 mCurrentFrame.drop[i] = true;
595 mCurrentFrame.dropCount++;
596 continue;
597 }
598
599 const hwc_layer_1_t* layer = &list->hwLayers[i];
600 hwc_rect_t dstRect = layer->displayFrame;
601
602 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
603 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
604 hwc_rect_t res = getUnion(l_res, r_res);
605
606 if(!isValidRect(l_res) && !isValidRect(r_res)) {
607 mCurrentFrame.drop[i] = true;
608 mCurrentFrame.dropCount++;
609 } else {
610 /* Reset frame ROI when any layer which needs scaling also needs ROI
611 * cropping */
612 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
613 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
614 mCurrentFrame.dropCount = 0;
615 return false;
616 }
617
618 if (layer->blending == HWC_BLENDING_NONE) {
619 visibleRectL = deductRect(visibleRectL, l_res);
620 visibleRectR = deductRect(visibleRectR, r_res);
621 }
622 }
623 }
624 return true;
625}
626/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
627 * are updating. If DirtyRegion is applicable, calculate it by accounting all
628 * the changing layer's dirtyRegion. */
629void MDPCompSplit::generateROI(hwc_context_t *ctx,
630 hwc_display_contents_1_t* list) {
631 if(!canPartialUpdate(ctx, list))
632 return;
633
634 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
635 int lSplit = getLeftSplit(ctx, mDpy);
636
637 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
638 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
639
640 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
641 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
642
643 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
644 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
645
646 for(int index = 0; index < numAppLayers; index++ ) {
647 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800648 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800649 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800650 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700651 hwc_rect_t dst = layer->displayFrame;
652 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800653
654#ifdef QCOM_BSP
655 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700656 {
657 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
658 int x_off = dst.left - src.left;
659 int y_off = dst.top - src.top;
660 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
661 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800662#endif
663
664 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
665 if(isValidRect(l_dst))
666 l_roi = getUnion(l_roi, l_dst);
667
668 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
669 if(isValidRect(r_dst))
670 r_roi = getUnion(r_roi, r_dst);
671 }
672 }
673
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700674 /* For panels that cannot accept commands in both the interfaces, we cannot
675 * send two ROI's (for each half). We merge them into single ROI and split
676 * them across lSplit for MDP mixer use. The ROI's will be merged again
677 * finally before udpating the panel in the driver. */
678 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
679 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
680 l_roi = getIntersection(temp_roi, l_frame);
681 r_roi = getIntersection(temp_roi, r_frame);
682 }
683
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800684 /* No layer is updating. Still SF wants a refresh. */
685 if(!isValidRect(l_roi) && !isValidRect(r_roi))
686 return;
687
688 l_roi = getSanitizeROI(l_roi, l_frame);
689 r_roi = getSanitizeROI(r_roi, r_frame);
690
691 ctx->listStats[mDpy].lRoi = l_roi;
692 ctx->listStats[mDpy].rRoi = r_roi;
693
694 if(!validateAndApplyROI(ctx, list))
695 resetROI(ctx, mDpy);
696
697 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
698 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
699 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
700 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
701 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
702 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700703}
704
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800705/* Checks for conditions where all the layers marked for MDP comp cannot be
706 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800707bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800708 hwc_display_contents_1_t* list){
709
Saurabh Shahaa236822013-04-24 18:07:26 -0700710 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800711 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800712
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400713 // No Idle fall back, if secure display or secure RGB layers are present or
714 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700715 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400716 !ctx->listStats[mDpy].secureRGBCount) &&
717 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700718 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
719 return false;
720 }
721
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800722 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700723 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
724 __FUNCTION__,
725 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800726 return false;
727 }
728
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700729 // if secondary is configuring or Padding round, fall back to video only
730 // composition and release all assigned non VIG pipes from primary.
731 if(isSecondaryConfiguring(ctx)) {
732 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
733 __FUNCTION__);
734 return false;
735 } else if(ctx->isPaddingRound) {
736 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
737 __FUNCTION__,mDpy);
738 return false;
739 }
740
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530741 MDPVersion& mdpHw = MDPVersion::getInstance();
742 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400743 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530744 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800745 // Disable MDP comp on Secondary when the primary is highres panel and
746 // the secondary is a normal 1080p, because, MDP comp on secondary under
747 // in such usecase, decimation gets used for downscale and there will be
748 // a quality mismatch when there will be a fallback to GPU comp
749 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
750 __FUNCTION__);
751 return false;
752 }
753
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700754 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800755 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700756 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800757 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
758 return false;
759 }
760
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800761 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800762 hwc_layer_1_t* layer = &list->hwLayers[i];
763 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800764
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800765 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700766 if(!canUseRotator(ctx, mDpy)) {
767 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
768 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700769 return false;
770 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800771 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530772
773 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
774 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700775 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530776 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
777 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
778 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800779 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700780
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700781 if(ctx->mAD->isDoable()) {
782 return false;
783 }
784
Saurabh Shahaa236822013-04-24 18:07:26 -0700785 //If all above hard conditions are met we can do full or partial MDP comp.
786 bool ret = false;
787 if(fullMDPComp(ctx, list)) {
788 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700789 } else if(fullMDPCompWithPTOR(ctx, list)) {
790 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700791 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700792 ret = true;
793 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530794
Saurabh Shahaa236822013-04-24 18:07:26 -0700795 return ret;
796}
797
798bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700799
800 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
801 return false;
802
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700803 //Will benefit presentation / secondary-only layer.
804 if((mDpy > HWC_DISPLAY_PRIMARY) &&
805 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
806 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
807 return false;
808 }
809
810 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
811 for(int i = 0; i < numAppLayers; i++) {
812 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700813 if(not mCurrentFrame.drop[i] and
814 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700815 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
816 return false;
817 }
818 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800819
Saurabh Shahaa236822013-04-24 18:07:26 -0700820 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700821 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
822 sizeof(mCurrentFrame.isFBComposed));
823 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
824 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700825
Raj Kamal389d6e32014-08-04 14:43:24 +0530826 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800827 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530828 }
829
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800830 if(!postHeuristicsHandling(ctx, list)) {
831 ALOGD_IF(isDebug(), "post heuristic handling failed");
832 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700833 return false;
834 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700835 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
836 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700837 return true;
838}
839
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840/* Full MDP Composition with Peripheral Tiny Overlap Removal.
841 * MDP bandwidth limitations can be avoided, if the overlap region
842 * covered by the smallest layer at a higher z-order, gets composed
843 * by Copybit on a render buffer, which can be queued to MDP.
844 */
845bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
846 hwc_display_contents_1_t* list) {
847
848 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
849 const int stagesForMDP = min(sMaxPipesPerMixer,
850 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
851
852 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700853 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700854 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
855 return false;
856 }
857
858 // Frame level checks
859 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
860 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
861 isSecurePresent(ctx, mDpy)) {
862 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
863 return false;
864 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700865 // MDP comp checks
866 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700867 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700868 if(not isSupportedForMDPComp(ctx, layer)) {
869 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
870 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700871 }
872 }
873
Sushil Chauhandefd3522014-05-13 18:17:12 -0700874 /* We cannot use this composition mode, if:
875 1. A below layer needs scaling.
876 2. Overlap is not peripheral to display.
877 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700878 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700879 */
880
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700881 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
882 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
883 memset(overlapRect, 0, sizeof(overlapRect));
884 int layerPixelCount, minPixelCount = 0;
885 int numPTORLayersFound = 0;
886 for (int i = numAppLayers-1; (i >= 0 &&
887 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700888 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700889 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700890 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700891 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
892 // PTOR layer should be peripheral and cannot have transform
893 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
894 has90Transform(layer)) {
895 continue;
896 }
897 if((3 * (layerPixelCount + minPixelCount)) >
898 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
899 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
900 continue;
901 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700902 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700903 for (int j = i-1; j >= 0; j--) {
904 // Check if the layers below this layer qualifies for PTOR comp
905 hwc_layer_1_t* layer = &list->hwLayers[j];
906 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700907 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700908 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700909 if (isValidRect(getIntersection(dispFrame, disFrame))) {
910 if (has90Transform(layer) || needsScaling(layer)) {
911 found = false;
912 break;
913 }
914 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700915 }
916 }
917 // Store the minLayer Index
918 if(found) {
919 minLayerIndex[numPTORLayersFound] = i;
920 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
921 minPixelCount += layerPixelCount;
922 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700923 }
924 }
925
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700926 // No overlap layers
927 if (!numPTORLayersFound)
928 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700929
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700930 // Store the displayFrame and the sourceCrops of the layers
931 hwc_rect_t displayFrame[numAppLayers];
932 hwc_rect_t sourceCrop[numAppLayers];
933 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700934 hwc_layer_1_t* layer = &list->hwLayers[i];
935 displayFrame[i] = layer->displayFrame;
936 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700937 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700938
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530939 /**
940 * It's possible that 2 PTOR layers might have overlapping.
941 * In such case, remove the intersection(again if peripheral)
942 * from the lower PTOR layer to avoid overlapping.
943 * If intersection is not on peripheral then compromise
944 * by reducing number of PTOR layers.
945 **/
946 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
947 if(isValidRect(commonRect)) {
948 overlapRect[1] = deductRect(overlapRect[1], commonRect);
949 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
950 }
951
952 ctx->mPtorInfo.count = numPTORLayersFound;
953 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
954 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
955 }
956
957 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
958 // reset PTOR
959 ctx->mPtorInfo.count = 0;
960 if(isValidRect(commonRect)) {
961 // If PTORs are intersecting restore displayframe of PTOR[1]
962 // before returning, as we have modified it above.
963 list->hwLayers[minLayerIndex[1]].displayFrame =
964 displayFrame[minLayerIndex[1]];
965 }
966 return false;
967 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700968 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
969 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
970
Xu Yangcda012c2014-07-30 21:57:21 +0800971 // Store the blending mode, planeAlpha, and transform of PTOR layers
972 int32_t blending[numPTORLayersFound];
973 uint8_t planeAlpha[numPTORLayersFound];
974 uint32_t transform[numPTORLayersFound];
975
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700976 for(int j = 0; j < numPTORLayersFound; j++) {
977 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700978
979 // Update src crop of PTOR layer
980 hwc_layer_1_t* layer = &list->hwLayers[index];
981 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
982 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
983 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
984 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
985
986 // Store & update w, h, format of PTOR layer
987 private_handle_t *hnd = (private_handle_t *)layer->handle;
988 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
989 layerWhf[j] = whf;
990 hnd->width = renderBuf->width;
991 hnd->height = renderBuf->height;
992 hnd->format = renderBuf->format;
993
Xu Yangcda012c2014-07-30 21:57:21 +0800994 // Store & update blending mode, planeAlpha and transform of PTOR layer
995 blending[j] = layer->blending;
996 planeAlpha[j] = layer->planeAlpha;
997 transform[j] = layer->transform;
998 layer->blending = HWC_BLENDING_NONE;
999 layer->planeAlpha = 0xFF;
1000 layer->transform = 0;
1001
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001002 // Remove overlap from crop & displayFrame of below layers
1003 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001004 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001005 if(!isValidRect(getIntersection(layer->displayFrame,
1006 overlapRect[j]))) {
1007 continue;
1008 }
1009 // Update layer attributes
1010 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1011 hwc_rect_t destRect = deductRect(layer->displayFrame,
1012 overlapRect[j]);
1013 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1014 layer->transform);
1015 layer->sourceCropf.left = (float)srcCrop.left;
1016 layer->sourceCropf.top = (float)srcCrop.top;
1017 layer->sourceCropf.right = (float)srcCrop.right;
1018 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1019 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001020 }
1021
1022 mCurrentFrame.mdpCount = numAppLayers;
1023 mCurrentFrame.fbCount = 0;
1024 mCurrentFrame.fbZ = -1;
1025
1026 for (int j = 0; j < numAppLayers; j++)
1027 mCurrentFrame.isFBComposed[j] = false;
1028
1029 bool result = postHeuristicsHandling(ctx, list);
1030
1031 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001032 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001033 hwc_layer_1_t* layer = &list->hwLayers[i];
1034 layer->displayFrame = displayFrame[i];
1035 layer->sourceCropf.left = (float)sourceCrop[i].left;
1036 layer->sourceCropf.top = (float)sourceCrop[i].top;
1037 layer->sourceCropf.right = (float)sourceCrop[i].right;
1038 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1039 }
1040
Xu Yangcda012c2014-07-30 21:57:21 +08001041 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001042 for (int i = 0; i < numPTORLayersFound; i++) {
1043 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001044 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001045 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1046 hnd->width = layerWhf[i].w;
1047 hnd->height = layerWhf[i].h;
1048 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001049 layer->blending = blending[i];
1050 layer->planeAlpha = planeAlpha[i];
1051 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001052 }
1053
Sushil Chauhandefd3522014-05-13 18:17:12 -07001054 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001055 // reset PTOR
1056 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001057 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001058 } else {
1059 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1060 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001061 }
1062
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001063 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1064 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001065 return result;
1066}
1067
Saurabh Shahaa236822013-04-24 18:07:26 -07001068bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1069{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001070 if(!sEnableMixedMode) {
1071 //Mixed mode is disabled. No need to even try caching.
1072 return false;
1073 }
1074
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001075 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001076 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001077 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001078 cacheBasedComp(ctx, list);
1079 } else {
1080 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001081 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001082 }
1083
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001084 return ret;
1085}
1086
1087bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1088 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001089 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1090 return false;
1091
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001092 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001093 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001094 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001095
1096 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1097 for(int i = 0; i < numAppLayers; i++) {
1098 if(!mCurrentFrame.isFBComposed[i]) {
1099 hwc_layer_1_t* layer = &list->hwLayers[i];
1100 if(not isSupportedForMDPComp(ctx, layer)) {
1101 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1102 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001103 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001104 return false;
1105 }
1106 }
1107 }
1108
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001109 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001110 /* mark secure RGB layers for MDP comp */
1111 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301112 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001113 if(!ret) {
1114 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001115 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001116 return false;
1117 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001118
1119 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001120
Raj Kamal389d6e32014-08-04 14:43:24 +05301121 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001122 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301123 }
1124
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001125 //Will benefit cases where a video has non-updating background.
1126 if((mDpy > HWC_DISPLAY_PRIMARY) and
1127 (mdpCount > MAX_SEC_LAYERS)) {
1128 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001129 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001130 return false;
1131 }
1132
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001133 if(!postHeuristicsHandling(ctx, list)) {
1134 ALOGD_IF(isDebug(), "post heuristic handling failed");
1135 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001136 return false;
1137 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001138 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1139 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001140
Saurabh Shahaa236822013-04-24 18:07:26 -07001141 return true;
1142}
1143
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001144bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001145 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001146 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1147 return false;
1148
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001149 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001150 return false;
1151 }
1152
Saurabh Shahb772ae32013-11-18 15:40:02 -08001153 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001154 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1155 const int stagesForMDP = min(sMaxPipesPerMixer,
1156 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001157
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001158 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1159 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1160 int lastMDPSupportedIndex = numAppLayers;
1161 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001162
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001163 //Find the minimum MDP batch size
1164 for(int i = 0; i < numAppLayers;i++) {
1165 if(mCurrentFrame.drop[i]) {
1166 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001167 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001168 }
1169 hwc_layer_1_t* layer = &list->hwLayers[i];
1170 if(not isSupportedForMDPComp(ctx, layer)) {
1171 lastMDPSupportedIndex = i;
1172 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1173 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001174 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001175 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001176 }
1177
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001178 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1179 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1180 mCurrentFrame.dropCount);
1181
1182 //Start at a point where the fb batch should at least have 2 layers, for
1183 //this mode to be justified.
1184 while(fbBatchSize < 2) {
1185 ++fbBatchSize;
1186 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001187 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001188
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001189 //If there are no layers for MDP, this mode doesnt make sense.
1190 if(mdpBatchSize < 1) {
1191 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1192 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001193 return false;
1194 }
1195
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001196 mCurrentFrame.reset(numAppLayers);
1197
1198 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1199 while(mdpBatchSize > 0) {
1200 //Mark layers for MDP comp
1201 int mdpBatchLeft = mdpBatchSize;
1202 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1203 if(mCurrentFrame.drop[i]) {
1204 continue;
1205 }
1206 mCurrentFrame.isFBComposed[i] = false;
1207 --mdpBatchLeft;
1208 }
1209
1210 mCurrentFrame.fbZ = mdpBatchSize;
1211 mCurrentFrame.fbCount = fbBatchSize;
1212 mCurrentFrame.mdpCount = mdpBatchSize;
1213
1214 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1215 __FUNCTION__, mdpBatchSize, fbBatchSize,
1216 mCurrentFrame.dropCount);
1217
1218 if(postHeuristicsHandling(ctx, list)) {
1219 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001220 __FUNCTION__);
1221 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1222 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001223 return true;
1224 }
1225
1226 reset(ctx);
1227 --mdpBatchSize;
1228 ++fbBatchSize;
1229 }
1230
1231 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001232}
1233
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001234bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301235 if(mDpy or isSecurePresent(ctx, mDpy) or
1236 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001237 return false;
1238 }
1239 return true;
1240}
1241
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001242bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1243 hwc_display_contents_1_t* list){
1244 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1245 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1246 mDpy ) {
1247 return false;
1248 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001249 if(ctx->listStats[mDpy].secureUI)
1250 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001251 return true;
1252}
1253
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001254bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1255 hwc_display_contents_1_t* list) {
1256 const bool secureOnly = true;
1257 return videoOnlyComp(ctx, list, not secureOnly) or
1258 videoOnlyComp(ctx, list, secureOnly);
1259}
1260
1261bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001262 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001263 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1264 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001265 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001266
Saurabh Shahaa236822013-04-24 18:07:26 -07001267 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001268 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001269 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001270 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001271
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001272 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1273 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001274 return false;
1275 }
1276
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001277 /* Bail out if we are processing only secured video layers
1278 * and we dont have any */
1279 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001280 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001281 return false;
1282 }
1283
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001284 if(mCurrentFrame.fbCount)
1285 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001286
Raj Kamal389d6e32014-08-04 14:43:24 +05301287 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001288 adjustForSourceSplit(ctx, list);
1289 }
1290
1291 if(!postHeuristicsHandling(ctx, list)) {
1292 ALOGD_IF(isDebug(), "post heuristic handling failed");
1293 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001294 return false;
1295 }
1296
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001297 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1298 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001299 return true;
1300}
1301
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001302/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1303bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1304 hwc_display_contents_1_t* list) {
1305 const bool secureOnly = true;
1306 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1307 mdpOnlyLayersComp(ctx, list, secureOnly);
1308
1309}
1310
1311bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1312 hwc_display_contents_1_t* list, bool secureOnly) {
1313
1314 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1315 return false;
1316
1317 /* Bail out if we are processing only secured video layers
1318 * and we dont have any */
1319 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1320 reset(ctx);
1321 return false;
1322 }
1323
1324 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1325 mCurrentFrame.reset(numAppLayers);
1326 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1327
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001328 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001329 /* mark secure RGB layers for MDP comp */
1330 updateSecureRGB(ctx, list);
1331
1332 if(mCurrentFrame.mdpCount == 0) {
1333 reset(ctx);
1334 return false;
1335 }
1336
1337 /* find the maximum batch of layers to be marked for framebuffer */
1338 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1339 if(!ret) {
1340 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1341 reset(ctx);
1342 return false;
1343 }
1344
1345 if(sEnableYUVsplit){
1346 adjustForSourceSplit(ctx, list);
1347 }
1348
1349 if(!postHeuristicsHandling(ctx, list)) {
1350 ALOGD_IF(isDebug(), "post heuristic handling failed");
1351 reset(ctx);
1352 return false;
1353 }
1354
1355 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1356 __FUNCTION__);
1357 return true;
1358}
1359
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001360/* Checks for conditions where YUV layers cannot be bypassed */
1361bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001362 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001363 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001364 return false;
1365 }
1366
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001367 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001368 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1369 return false;
1370 }
1371
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001372 if(isSecuring(ctx, layer)) {
1373 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1374 return false;
1375 }
1376
Saurabh Shah4fdde762013-04-30 18:47:33 -07001377 if(!isValidDimension(ctx, layer)) {
1378 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1379 __FUNCTION__);
1380 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001381 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001382
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001383 if(layer->planeAlpha < 0xFF) {
1384 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1385 in video only mode",
1386 __FUNCTION__);
1387 return false;
1388 }
1389
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001390 return true;
1391}
1392
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001393/* Checks for conditions where Secure RGB layers cannot be bypassed */
1394bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1395 if(isSkipLayer(layer)) {
1396 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1397 __FUNCTION__, mDpy);
1398 return false;
1399 }
1400
1401 if(isSecuring(ctx, layer)) {
1402 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1403 return false;
1404 }
1405
1406 if(not isSupportedForMDPComp(ctx, layer)) {
1407 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1408 __FUNCTION__);
1409 return false;
1410 }
1411 return true;
1412}
1413
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301414/* starts at fromIndex and check for each layer to find
1415 * if it it has overlapping with any Updating layer above it in zorder
1416 * till the end of the batch. returns true if it finds any intersection */
1417bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1418 int fromIndex, int toIndex) {
1419 for(int i = fromIndex; i < toIndex; i++) {
1420 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1421 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1422 return false;
1423 }
1424 }
1425 }
1426 return true;
1427}
1428
1429/* Checks if given layer at targetLayerIndex has any
1430 * intersection with all the updating layers in beween
1431 * fromIndex and toIndex. Returns true if it finds intersectiion */
1432bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1433 int fromIndex, int toIndex, int targetLayerIndex) {
1434 for(int i = fromIndex; i <= toIndex; i++) {
1435 if(!mCurrentFrame.isFBComposed[i]) {
1436 if(areLayersIntersecting(&list->hwLayers[i],
1437 &list->hwLayers[targetLayerIndex])) {
1438 return true;
1439 }
1440 }
1441 }
1442 return false;
1443}
1444
1445int MDPComp::getBatch(hwc_display_contents_1_t* list,
1446 int& maxBatchStart, int& maxBatchEnd,
1447 int& maxBatchCount) {
1448 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301449 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001450 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301451 while (i < mCurrentFrame.layerCount) {
1452 int batchCount = 0;
1453 int batchStart = i;
1454 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001455 /* Adjust batch Z order with the dropped layers so far */
1456 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301457 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301458 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301459 while(i < mCurrentFrame.layerCount) {
1460 if(!mCurrentFrame.isFBComposed[i]) {
1461 if(!batchCount) {
1462 i++;
1463 break;
1464 }
1465 updatingLayersAbove++;
1466 i++;
1467 continue;
1468 } else {
1469 if(mCurrentFrame.drop[i]) {
1470 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001471 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301472 continue;
1473 } else if(updatingLayersAbove <= 0) {
1474 batchCount++;
1475 batchEnd = i;
1476 i++;
1477 continue;
1478 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1479
1480 // We have a valid updating layer already. If layer-i not
1481 // have overlapping with all updating layers in between
1482 // batch-start and i, then we can add layer i to batch.
1483 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1484 batchCount++;
1485 batchEnd = i;
1486 i++;
1487 continue;
1488 } else if(canPushBatchToTop(list, batchStart, i)) {
1489 //If All the non-updating layers with in this batch
1490 //does not have intersection with the updating layers
1491 //above in z-order, then we can safely move the batch to
1492 //higher z-order. Increment fbZ as it is moving up.
1493 if( firstZReverseIndex < 0) {
1494 firstZReverseIndex = i;
1495 }
1496 batchCount++;
1497 batchEnd = i;
1498 fbZ += updatingLayersAbove;
1499 i++;
1500 updatingLayersAbove = 0;
1501 continue;
1502 } else {
1503 //both failed.start the loop again from here.
1504 if(firstZReverseIndex >= 0) {
1505 i = firstZReverseIndex;
1506 }
1507 break;
1508 }
1509 }
1510 }
1511 }
1512 if(batchCount > maxBatchCount) {
1513 maxBatchCount = batchCount;
1514 maxBatchStart = batchStart;
1515 maxBatchEnd = batchEnd;
1516 fbZOrder = fbZ;
1517 }
1518 }
1519 return fbZOrder;
1520}
1521
1522bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1523 hwc_display_contents_1_t* list) {
1524 /* Idea is to keep as many non-updating(cached) layers in FB and
1525 * send rest of them through MDP. This is done in 2 steps.
1526 * 1. Find the maximum contiguous batch of non-updating layers.
1527 * 2. See if we can improve this batch size for caching by adding
1528 * opaque layers around the batch, if they don't have
1529 * any overlapping with the updating layers in between.
1530 * NEVER mark an updating layer for caching.
1531 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001532
1533 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001534 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001535 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301536 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001537
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001538 /* Nothing is cached. No batching needed */
1539 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001540 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001541 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001542
1543 /* No MDP comp layers, try to use other comp modes */
1544 if(mCurrentFrame.mdpCount == 0) {
1545 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001546 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001547
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301548 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001549
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301550 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001551 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001552 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001553 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301554 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001555 if(!mCurrentFrame.drop[i]){
1556 //If an unsupported layer is being attempted to
1557 //be pulled out we should fail
1558 if(not isSupportedForMDPComp(ctx, layer)) {
1559 return false;
1560 }
1561 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001562 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563 }
1564 }
1565
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301566 // update the frame data
1567 mCurrentFrame.fbZ = fbZ;
1568 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001569 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001570 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001571
1572 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301573 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001574
1575 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001576}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001577
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001578void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001579 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001580 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001581 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001582
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583 for(int i = 0; i < numAppLayers; i++) {
1584 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001585 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001586 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001587 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001588 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001589 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001590 }
1591 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001592
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001593 frame.fbCount = fbCount;
1594 frame.mdpCount = frame.layerCount - frame.fbCount
1595 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001596
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001597 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1598 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001599}
1600
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001601void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001602 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001603 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1604 for(int index = 0;index < nYuvCount; index++){
1605 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1606 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1607
1608 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001609 if(!frame.isFBComposed[nYuvIndex]) {
1610 frame.isFBComposed[nYuvIndex] = true;
1611 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612 }
1613 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001614 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001615 private_handle_t *hnd = (private_handle_t *)layer->handle;
1616 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001617 frame.isFBComposed[nYuvIndex] = false;
1618 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001619 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001620 }
1621 }
1622 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001623
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001624 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1625 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626}
1627
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001628void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1629 hwc_display_contents_1_t* list) {
1630 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1631 for(int index = 0;index < nSecureRGBCount; index++){
1632 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1633 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1634
1635 if(!isSecureRGBDoable(ctx, layer)) {
1636 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1637 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1638 mCurrentFrame.fbCount++;
1639 }
1640 } else {
1641 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1642 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1643 mCurrentFrame.fbCount--;
1644 }
1645 }
1646 }
1647
1648 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1649 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1650 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1651 mCurrentFrame.fbCount);
1652}
1653
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001654hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1655 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001656 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001657
1658 /* Update only the region of FB needed for composition */
1659 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1660 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1661 hwc_layer_1_t* layer = &list->hwLayers[i];
1662 hwc_rect_t dst = layer->displayFrame;
1663 fbRect = getUnion(fbRect, dst);
1664 }
1665 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001666 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001667 return fbRect;
1668}
1669
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001670bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1671 hwc_display_contents_1_t* list) {
1672
1673 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001674 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001675 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1676 return false;
1677 }
1678
1679 //Limitations checks
1680 if(!hwLimitationsCheck(ctx, list)) {
1681 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1682 return false;
1683 }
1684
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001685 //Configure framebuffer first if applicable
1686 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001687 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001688 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1689 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001690 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1691 __FUNCTION__);
1692 return false;
1693 }
1694 }
1695
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001696 mCurrentFrame.map();
1697
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001698 if(!allocLayerPipes(ctx, list)) {
1699 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001700 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001701 }
1702
1703 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001704 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001705 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001706 int mdpIndex = mCurrentFrame.layerToMDP[index];
1707 hwc_layer_1_t* layer = &list->hwLayers[index];
1708
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301709 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1710 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1711 mdpNextZOrder++;
1712 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001713 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1714 cur_pipe->zOrder = mdpNextZOrder++;
1715
radhakrishnac9a67412013-09-25 17:40:42 +05301716 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301717 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301718 if(configure4k2kYuv(ctx, layer,
1719 mCurrentFrame.mdpToLayer[mdpIndex])
1720 != 0 ){
1721 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1722 for layer %d",__FUNCTION__, index);
1723 return false;
1724 }
1725 else{
1726 mdpNextZOrder++;
1727 }
1728 continue;
1729 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001730 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1731 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301732 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001733 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001734 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001735 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001736 }
1737
Saurabh Shaha36be922013-12-16 18:18:39 -08001738 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1739 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1740 ,__FUNCTION__, mDpy);
1741 return false;
1742 }
1743
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001744 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001745 return true;
1746}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001747
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001748bool MDPComp::resourceCheck(hwc_context_t* ctx,
1749 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001750 const bool fbUsed = mCurrentFrame.fbCount;
1751 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1752 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1753 return false;
1754 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001755 // Init rotCount to number of rotate sessions used by other displays
1756 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1757 // Count the number of rotator sessions required for current display
1758 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1759 if(!mCurrentFrame.isFBComposed[index]) {
1760 hwc_layer_1_t* layer = &list->hwLayers[index];
1761 private_handle_t *hnd = (private_handle_t *)layer->handle;
1762 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1763 rotCount++;
1764 }
1765 }
1766 }
1767 // if number of layers to rotate exceeds max rotator sessions, bail out.
1768 if(rotCount > RotMgr::MAX_ROT_SESS) {
1769 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1770 __FUNCTION__, mDpy);
1771 return false;
1772 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001773 return true;
1774}
1775
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301776bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1777 hwc_display_contents_1_t* list) {
1778
1779 //A-family hw limitation:
1780 //If a layer need alpha scaling, MDP can not support.
1781 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1782 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1783 if(!mCurrentFrame.isFBComposed[i] &&
1784 isAlphaScaled( &list->hwLayers[i])) {
1785 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1786 return false;
1787 }
1788 }
1789 }
1790
1791 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1792 //If multiple layers requires downscaling and also they are overlapping
1793 //fall back to GPU since MDSS can not handle it.
1794 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1795 qdutils::MDPVersion::getInstance().is8x26()) {
1796 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1797 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1798 if(!mCurrentFrame.isFBComposed[i] &&
1799 isDownscaleRequired(botLayer)) {
1800 //if layer-i is marked for MDP and needs downscaling
1801 //check if any MDP layer on top of i & overlaps with layer-i
1802 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1803 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1804 if(!mCurrentFrame.isFBComposed[j] &&
1805 isDownscaleRequired(topLayer)) {
1806 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1807 topLayer->displayFrame);
1808 if(isValidRect(r))
1809 return false;
1810 }
1811 }
1812 }
1813 }
1814 }
1815 return true;
1816}
1817
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001818int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001819 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001820 char property[PROPERTY_VALUE_MAX];
1821
Raj Kamal4393eaa2014-06-06 13:45:20 +05301822 if(!ctx || !list) {
1823 ALOGE("%s: Invalid context or list",__FUNCTION__);
1824 mCachedFrame.reset();
1825 return -1;
1826 }
1827
1828 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001829 if(mDpy == HWC_DISPLAY_PRIMARY) {
1830 sSimulationFlags = 0;
1831 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1832 int currentFlags = atoi(property);
1833 if(currentFlags != sSimulationFlags) {
1834 sSimulationFlags = currentFlags;
1835 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1836 sSimulationFlags, sSimulationFlags);
1837 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001838 }
1839 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001840 // reset PTOR
1841 if(!mDpy)
1842 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001843
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301844 //Do not cache the information for next draw cycle.
1845 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1846 ALOGI("%s: Unsupported layer count for mdp composition",
1847 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001848 mCachedFrame.reset();
1849 return -1;
1850 }
1851
Saurabh Shahb39f8152013-08-22 10:21:44 -07001852 //reset old data
1853 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001854 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1855 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301856
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001857 // Detect the start of animation and fall back to GPU only once to cache
1858 // all the layers in FB and display FB content untill animation completes.
1859 if(ctx->listStats[mDpy].isDisplayAnimating) {
1860 mCurrentFrame.needsRedraw = false;
1861 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1862 mCurrentFrame.needsRedraw = true;
1863 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1864 }
1865 setMDPCompLayerFlags(ctx, list);
1866 mCachedFrame.updateCounts(mCurrentFrame);
1867 ret = -1;
1868 return ret;
1869 } else {
1870 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1871 }
1872
Saurabh Shahb39f8152013-08-22 10:21:44 -07001873 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001874 if(isFrameDoable(ctx)) {
1875 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001876
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001877 // if tryFullFrame fails, try to push all video and secure RGB layers
1878 // to MDP for composition.
1879 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
1880 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301881 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001882 setMDPCompLayerFlags(ctx, list);
1883 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001884 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001885 reset(ctx);
1886 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1887 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001888 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001889 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1890 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001891 }
1892 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301893 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1894 enablePartialUpdateForMDP3) {
1895 generateROI(ctx, list);
1896 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1897 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1898 }
1899 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001900 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1901 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001902 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001903 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001904
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001905 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001906 ALOGD("GEOMETRY change: %d",
1907 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001908 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001909 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001910 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001911 }
1912
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001913#ifdef DYNAMIC_FPS
1914 //For primary display, set the dynamic refreshrate
1915 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1916 FrameInfo frame;
1917 frame.reset(mCurrentFrame.layerCount);
1918 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1919 __FUNCTION__);
1920 updateLayerCache(ctx, list, frame);
1921 updateYUV(ctx, list, false /*secure only*/, frame);
1922 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1923 //Set the new fresh rate, if there is only one updating YUV layer
1924 //or there is one single RGB layer with this request
1925 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1926 (frame.layerCount == 1)) {
1927 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1928 }
1929 setRefreshRate(ctx, mDpy, refreshRate);
1930 }
1931#endif
1932
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001933 mCachedFrame.cacheAll(list);
1934 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001935 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001936}
1937
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001938bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301939
1940 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301941 int mdpIndex = mCurrentFrame.layerToMDP[index];
1942 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1943 info.pipeInfo = new MdpYUVPipeInfo;
1944 info.rot = NULL;
1945 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301946
1947 pipe_info.lIndex = ovutils::OV_INVALID;
1948 pipe_info.rIndex = ovutils::OV_INVALID;
1949
Saurabh Shahc62f3982014-03-05 14:28:26 -08001950 Overlay::PipeSpecs pipeSpecs;
1951 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1952 pipeSpecs.needsScaling = true;
1953 pipeSpecs.dpy = mDpy;
1954 pipeSpecs.fb = false;
1955
1956 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301957 if(pipe_info.lIndex == ovutils::OV_INVALID){
1958 bRet = false;
1959 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1960 __FUNCTION__);
1961 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001962 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301963 if(pipe_info.rIndex == ovutils::OV_INVALID){
1964 bRet = false;
1965 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1966 __FUNCTION__);
1967 }
1968 return bRet;
1969}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001970
1971int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1972 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001973 if (ctx->mPtorInfo.isActive()) {
1974 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001975 if (fd < 0) {
1976 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001977 }
1978 }
1979 return fd;
1980}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001981//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001982
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001983void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301984 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001985 //If 4k2k Yuv layer split is possible, and if
1986 //fbz is above 4k2k layer, increment fb zorder by 1
1987 //as we split 4k2k layer and increment zorder for right half
1988 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001989 if(!ctx)
1990 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001991 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301992 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1993 index++) {
1994 if(!mCurrentFrame.isFBComposed[index]) {
1995 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1996 mdpNextZOrder++;
1997 }
1998 mdpNextZOrder++;
1999 hwc_layer_1_t* layer = &list->hwLayers[index];
2000 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302001 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302002 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2003 mCurrentFrame.fbZ += 1;
2004 mdpNextZOrder++;
2005 //As we split 4kx2k yuv layer and program to 2 VG pipes
2006 //(if available) increase mdpcount by 1.
2007 mCurrentFrame.mdpCount++;
2008 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002009 }
2010 }
2011 }
radhakrishnac9a67412013-09-25 17:40:42 +05302012}
2013
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002014/*
2015 * Configures pipe(s) for MDP composition
2016 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002017int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002018 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002019 MdpPipeInfoNonSplit& mdp_info =
2020 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002021 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2022 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002023 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002024
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002025 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2026 __FUNCTION__, layer, zOrder, dest);
2027
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002028 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002029 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002030}
2031
Saurabh Shah88e4d272013-09-03 13:31:29 -07002032bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002033 hwc_display_contents_1_t* list) {
2034 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002035
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002036 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002037
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002038 hwc_layer_1_t* layer = &list->hwLayers[index];
2039 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302040 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002041 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302042 continue;
2043 }
2044 }
2045
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002046 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002047 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002048 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002049 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002050 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002051
Saurabh Shahc62f3982014-03-05 14:28:26 -08002052 Overlay::PipeSpecs pipeSpecs;
2053 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2054 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2055 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2056 (qdutils::MDPVersion::getInstance().is8x26() and
2057 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2058 pipeSpecs.dpy = mDpy;
2059 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002060 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002061
Saurabh Shahc62f3982014-03-05 14:28:26 -08002062 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2063
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002064 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002065 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002066 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002067 }
2068 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002069 return true;
2070}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002071
radhakrishnac9a67412013-09-25 17:40:42 +05302072int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2073 PipeLayerPair& PipeLayerPair) {
2074 MdpYUVPipeInfo& mdp_info =
2075 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2076 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302077 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2078 eDest lDest = mdp_info.lIndex;
2079 eDest rDest = mdp_info.rIndex;
2080
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002081 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302082 lDest, rDest, &PipeLayerPair.rot);
2083}
2084
Saurabh Shah88e4d272013-09-03 13:31:29 -07002085bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002086
Raj Kamal4393eaa2014-06-06 13:45:20 +05302087 if(!isEnabled() or !mModeOn) {
2088 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302089 return true;
2090 }
2091
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002092 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002093 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002094 sHandleTimeout = true;
2095 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002096
2097 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002098 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002099
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002100 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2101 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002102 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002103 if(mCurrentFrame.isFBComposed[i]) continue;
2104
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002105 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002106 private_handle_t *hnd = (private_handle_t *)layer->handle;
2107 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002108 if (!(layer->flags & HWC_COLOR_FILL)) {
2109 ALOGE("%s handle null", __FUNCTION__);
2110 return false;
2111 }
2112 // No PLAY for Color layer
2113 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2114 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002115 }
2116
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002117 int mdpIndex = mCurrentFrame.layerToMDP[i];
2118
Raj Kamal389d6e32014-08-04 14:43:24 +05302119 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302120 {
2121 MdpYUVPipeInfo& pipe_info =
2122 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2123 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2124 ovutils::eDest indexL = pipe_info.lIndex;
2125 ovutils::eDest indexR = pipe_info.rIndex;
2126 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302127 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302128 if(rot) {
2129 rot->queueBuffer(fd, offset);
2130 fd = rot->getDstMemId();
2131 offset = rot->getDstOffset();
2132 }
2133 if(indexL != ovutils::OV_INVALID) {
2134 ovutils::eDest destL = (ovutils::eDest)indexL;
2135 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2136 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2137 if (!ov.queueBuffer(fd, offset, destL)) {
2138 ALOGE("%s: queueBuffer failed for display:%d",
2139 __FUNCTION__, mDpy);
2140 return false;
2141 }
2142 }
2143
2144 if(indexR != ovutils::OV_INVALID) {
2145 ovutils::eDest destR = (ovutils::eDest)indexR;
2146 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2147 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2148 if (!ov.queueBuffer(fd, offset, destR)) {
2149 ALOGE("%s: queueBuffer failed for display:%d",
2150 __FUNCTION__, mDpy);
2151 return false;
2152 }
2153 }
2154 }
2155 else{
2156 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002157 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302158 ovutils::eDest dest = pipe_info.index;
2159 if(dest == ovutils::OV_INVALID) {
2160 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002161 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302162 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002163
radhakrishnac9a67412013-09-25 17:40:42 +05302164 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2165 continue;
2166 }
2167
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002168 int fd = hnd->fd;
2169 uint32_t offset = (uint32_t)hnd->offset;
2170 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2171 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002172 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002173 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002174 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002175 }
2176
radhakrishnac9a67412013-09-25 17:40:42 +05302177 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2178 using pipe: %d", __FUNCTION__, layer,
2179 hnd, dest );
2180
radhakrishnac9a67412013-09-25 17:40:42 +05302181 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2182 if(rot) {
2183 if(!rot->queueBuffer(fd, offset))
2184 return false;
2185 fd = rot->getDstMemId();
2186 offset = rot->getDstOffset();
2187 }
2188
2189 if (!ov.queueBuffer(fd, offset, dest)) {
2190 ALOGE("%s: queueBuffer failed for display:%d ",
2191 __FUNCTION__, mDpy);
2192 return false;
2193 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002194 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002195
2196 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002197 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002198 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002199}
2200
Saurabh Shah88e4d272013-09-03 13:31:29 -07002201//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002202
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002203void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302204 hwc_display_contents_1_t* list){
2205 //if 4kx2k yuv layer is totally present in either in left half
2206 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302207 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302208 if(mCurrentFrame.fbZ >= 0) {
2209 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2210 index++) {
2211 if(!mCurrentFrame.isFBComposed[index]) {
2212 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2213 mdpNextZOrder++;
2214 }
2215 mdpNextZOrder++;
2216 hwc_layer_1_t* layer = &list->hwLayers[index];
2217 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302218 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302219 hwc_rect_t dst = layer->displayFrame;
2220 if((dst.left > lSplit) || (dst.right < lSplit)) {
2221 mCurrentFrame.mdpCount += 1;
2222 }
2223 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2224 mCurrentFrame.fbZ += 1;
2225 mdpNextZOrder++;
2226 }
2227 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002228 }
radhakrishnac9a67412013-09-25 17:40:42 +05302229 }
2230}
2231
Saurabh Shah88e4d272013-09-03 13:31:29 -07002232bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002233 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002234
Saurabh Shahc62f3982014-03-05 14:28:26 -08002235 const int lSplit = getLeftSplit(ctx, mDpy);
2236 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002237 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002238 pipe_info.lIndex = ovutils::OV_INVALID;
2239 pipe_info.rIndex = ovutils::OV_INVALID;
2240
Saurabh Shahc62f3982014-03-05 14:28:26 -08002241 Overlay::PipeSpecs pipeSpecs;
2242 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2243 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2244 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2245 pipeSpecs.dpy = mDpy;
2246 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2247 pipeSpecs.fb = false;
2248
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002249 // Acquire pipe only for the updating half
2250 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2251 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2252
2253 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002254 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002255 if(pipe_info.lIndex == ovutils::OV_INVALID)
2256 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002257 }
2258
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002259 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002260 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2261 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002262 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002263 return false;
2264 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002265
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002266 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002267}
2268
Saurabh Shah88e4d272013-09-03 13:31:29 -07002269bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002270 hwc_display_contents_1_t* list) {
2271 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002272
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002273 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002274
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002275 hwc_layer_1_t* layer = &list->hwLayers[index];
2276 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302277 hwc_rect_t dst = layer->displayFrame;
2278 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302279 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302280 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002281 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302282 continue;
2283 }
2284 }
2285 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002286 int mdpIndex = mCurrentFrame.layerToMDP[index];
2287 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002288 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002289 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002290 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002291
Saurabh Shahc62f3982014-03-05 14:28:26 -08002292 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2293 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2294 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002295 return false;
2296 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002297 }
2298 return true;
2299}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002300
radhakrishnac9a67412013-09-25 17:40:42 +05302301int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2302 PipeLayerPair& PipeLayerPair) {
2303 const int lSplit = getLeftSplit(ctx, mDpy);
2304 hwc_rect_t dst = layer->displayFrame;
2305 if((dst.left > lSplit)||(dst.right < lSplit)){
2306 MdpYUVPipeInfo& mdp_info =
2307 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2308 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
radhakrishnac9a67412013-09-25 17:40:42 +05302309 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2310 eDest lDest = mdp_info.lIndex;
2311 eDest rDest = mdp_info.rIndex;
2312
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002313 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302314 lDest, rDest, &PipeLayerPair.rot);
2315 }
2316 else{
2317 return configure(ctx, layer, PipeLayerPair);
2318 }
2319}
2320
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002321/*
2322 * Configures pipe(s) for MDP composition
2323 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002324int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002325 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002326 MdpPipeInfoSplit& mdp_info =
2327 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002328 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002329 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2330 eDest lDest = mdp_info.lIndex;
2331 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002332
2333 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2334 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2335
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002336 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002337 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002338}
2339
Saurabh Shah88e4d272013-09-03 13:31:29 -07002340bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002341
Raj Kamal4393eaa2014-06-06 13:45:20 +05302342 if(!isEnabled() or !mModeOn) {
2343 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302344 return true;
2345 }
2346
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002347 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002348 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002349 sHandleTimeout = true;
2350 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002351
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002352 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002353 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002354
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002355 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2356 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002357 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002358 if(mCurrentFrame.isFBComposed[i]) continue;
2359
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002360 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002361 private_handle_t *hnd = (private_handle_t *)layer->handle;
2362 if(!hnd) {
2363 ALOGE("%s handle null", __FUNCTION__);
2364 return false;
2365 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002366
2367 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2368 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002369 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002370
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002371 int mdpIndex = mCurrentFrame.layerToMDP[i];
2372
Raj Kamal389d6e32014-08-04 14:43:24 +05302373 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302374 {
2375 MdpYUVPipeInfo& pipe_info =
2376 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2377 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2378 ovutils::eDest indexL = pipe_info.lIndex;
2379 ovutils::eDest indexR = pipe_info.rIndex;
2380 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302381 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302382 if(rot) {
2383 rot->queueBuffer(fd, offset);
2384 fd = rot->getDstMemId();
2385 offset = rot->getDstOffset();
2386 }
2387 if(indexL != ovutils::OV_INVALID) {
2388 ovutils::eDest destL = (ovutils::eDest)indexL;
2389 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2390 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2391 if (!ov.queueBuffer(fd, offset, destL)) {
2392 ALOGE("%s: queueBuffer failed for display:%d",
2393 __FUNCTION__, mDpy);
2394 return false;
2395 }
2396 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002397
radhakrishnac9a67412013-09-25 17:40:42 +05302398 if(indexR != ovutils::OV_INVALID) {
2399 ovutils::eDest destR = (ovutils::eDest)indexR;
2400 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2401 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2402 if (!ov.queueBuffer(fd, offset, destR)) {
2403 ALOGE("%s: queueBuffer failed for display:%d",
2404 __FUNCTION__, mDpy);
2405 return false;
2406 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002407 }
2408 }
radhakrishnac9a67412013-09-25 17:40:42 +05302409 else{
2410 MdpPipeInfoSplit& pipe_info =
2411 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2412 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002413
radhakrishnac9a67412013-09-25 17:40:42 +05302414 ovutils::eDest indexL = pipe_info.lIndex;
2415 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002416
radhakrishnac9a67412013-09-25 17:40:42 +05302417 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002418 uint32_t offset = (uint32_t)hnd->offset;
2419 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2420 if (!mDpy && (index != -1)) {
2421 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2422 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002423 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002424 }
radhakrishnac9a67412013-09-25 17:40:42 +05302425
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002426 if(ctx->mAD->draw(ctx, fd, offset)) {
2427 fd = ctx->mAD->getDstFd();
2428 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002429 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002430
radhakrishnac9a67412013-09-25 17:40:42 +05302431 if(rot) {
2432 rot->queueBuffer(fd, offset);
2433 fd = rot->getDstMemId();
2434 offset = rot->getDstOffset();
2435 }
2436
2437 //************* play left mixer **********
2438 if(indexL != ovutils::OV_INVALID) {
2439 ovutils::eDest destL = (ovutils::eDest)indexL;
2440 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2441 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2442 if (!ov.queueBuffer(fd, offset, destL)) {
2443 ALOGE("%s: queueBuffer failed for left mixer",
2444 __FUNCTION__);
2445 return false;
2446 }
2447 }
2448
2449 //************* play right mixer **********
2450 if(indexR != ovutils::OV_INVALID) {
2451 ovutils::eDest destR = (ovutils::eDest)indexR;
2452 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2453 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2454 if (!ov.queueBuffer(fd, offset, destR)) {
2455 ALOGE("%s: queueBuffer failed for right mixer",
2456 __FUNCTION__);
2457 return false;
2458 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002459 }
2460 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002461
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002462 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2463 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002464
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002465 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002466}
Saurabh Shahab47c692014-02-12 18:45:57 -08002467
2468//================MDPCompSrcSplit==============================================
2469bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002470 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002471 private_handle_t *hnd = (private_handle_t *)layer->handle;
2472 hwc_rect_t dst = layer->displayFrame;
2473 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2474 pipe_info.lIndex = ovutils::OV_INVALID;
2475 pipe_info.rIndex = ovutils::OV_INVALID;
2476
2477 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2478 //should have a higher priority than the right one. Pipe priorities are
2479 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002480
Saurabh Shahc62f3982014-03-05 14:28:26 -08002481 Overlay::PipeSpecs pipeSpecs;
2482 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2483 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2484 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2485 pipeSpecs.dpy = mDpy;
2486 pipeSpecs.fb = false;
2487
Saurabh Shahab47c692014-02-12 18:45:57 -08002488 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002489 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002490 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002491 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002492 }
2493
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002494 /* Use 2 pipes IF
2495 a) Layer's crop width is > 2048 or
2496 b) Layer's dest width > 2048 or
2497 c) On primary, driver has indicated with caps to split always. This is
2498 based on an empirically derived value of panel height. Applied only
2499 if the layer's width is > mixer's width
2500 */
2501
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302502 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002503 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302504 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002505 int lSplit = getLeftSplit(ctx, mDpy);
2506 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002507 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2508 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002509
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002510 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2511 //pipe line length, we are still using 2 pipes. This is fine just because
2512 //this is source split where destination doesn't matter. Evaluate later to
2513 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002514 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2515 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002516 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002517 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002518 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002519 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002520 }
2521
2522 // Return values
2523 // 1 Left pipe is higher priority, do nothing.
2524 // 0 Pipes of same priority.
2525 //-1 Right pipe is of higher priority, needs swap.
2526 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2527 pipe_info.rIndex) == -1) {
2528 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002529 }
2530 }
2531
2532 return true;
2533}
2534
Saurabh Shahab47c692014-02-12 18:45:57 -08002535int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2536 PipeLayerPair& PipeLayerPair) {
2537 private_handle_t *hnd = (private_handle_t *)layer->handle;
2538 if(!hnd) {
2539 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2540 return -1;
2541 }
2542 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2543 MdpPipeInfoSplit& mdp_info =
2544 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2545 Rotator **rot = &PipeLayerPair.rot;
2546 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002547 eDest lDest = mdp_info.lIndex;
2548 eDest rDest = mdp_info.rIndex;
2549 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2550 hwc_rect_t dst = layer->displayFrame;
2551 int transform = layer->transform;
2552 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002553 int rotFlags = ROT_FLAGS_NONE;
2554 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2555 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2556
2557 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2558 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2559
2560 // Handle R/B swap
2561 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2562 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2563 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2564 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2565 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2566 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002567 /* Calculate the external display position based on MDP downscale,
2568 ActionSafe, and extorientation features. */
2569 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002570
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002571 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002572 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002573 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002574
2575 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2576 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002577 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002578 }
2579
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002580 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002581 (*rot) = ctx->mRotMgr->getNext();
2582 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002583 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002584 //If the video is using a single pipe, enable BWC
2585 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002586 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002587 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002588 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002589 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002590 ALOGE("%s: configRotator failed!", __FUNCTION__);
2591 return -1;
2592 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002593 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002594 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002595 }
2596
2597 //If 2 pipes being used, divide layer into half, crop and dst
2598 hwc_rect_t cropL = crop;
2599 hwc_rect_t cropR = crop;
2600 hwc_rect_t dstL = dst;
2601 hwc_rect_t dstR = dst;
2602 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2603 cropL.right = (crop.right + crop.left) / 2;
2604 cropR.left = cropL.right;
2605 sanitizeSourceCrop(cropL, cropR, hnd);
2606
Saurabh Shahb729b192014-08-15 18:04:24 -07002607 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002608 //Swap crops on H flip since 2 pipes are being used
2609 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2610 hwc_rect_t tmp = cropL;
2611 cropL = cropR;
2612 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002613 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002614 }
2615
Saurabh Shahb729b192014-08-15 18:04:24 -07002616 //cropSwap trick: If the src and dst widths are both odd, let us say
2617 //2507, then splitting both into half would cause left width to be 1253
2618 //and right 1254. If crop is swapped because of H flip, this will cause
2619 //left crop width to be 1254, whereas left dst width remains 1253, thus
2620 //inducing a scaling that is unaccounted for. To overcome that we add 1
2621 //to the dst width if there is a cropSwap. So if the original width was
2622 //2507, the left dst width will be 1254. Even if the original width was
2623 //even for ex: 2508, the left dst width will still remain 1254.
2624 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002625 dstR.left = dstL.right;
2626 }
2627
2628 //For the mdp, since either we are pre-rotating or MDP does flips
2629 orient = OVERLAY_TRANSFORM_0;
2630 transform = 0;
2631
2632 //configure left pipe
2633 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002634 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002635 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2636 (ovutils::eBlending) getBlending(layer->blending));
2637
2638 if(configMdp(ctx->mOverlay, pargL, orient,
2639 cropL, dstL, metadata, lDest) < 0) {
2640 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2641 return -1;
2642 }
2643 }
2644
2645 //configure right pipe
2646 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002647 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002648 static_cast<eRotFlags>(rotFlags),
2649 layer->planeAlpha,
2650 (ovutils::eBlending) getBlending(layer->blending));
2651 if(configMdp(ctx->mOverlay, pargR, orient,
2652 cropR, dstR, metadata, rDest) < 0) {
2653 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2654 return -1;
2655 }
2656 }
2657
2658 return 0;
2659}
2660
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002661}; //namespace
2662