blob: cf68a3a78805eb15f547241c16beb7a48f26e94c [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>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
radhakrishnac9a67412013-09-25 17:40:42 +053048bool MDPComp::sEnable4k2kYUVSplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = 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 Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
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
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800130 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
131 if(atoi(property) != 0)
132 sDebugLogs = true;
133 }
134
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700136 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
137 int val = atoi(property);
138 if(val >= 0)
139 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800140 }
141
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400142 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
143 // Idle invalidation is not necessary on command mode panels
144 long idle_timeout = DEFAULT_IDLE_TIME;
145 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
146 if(atoi(property) != 0)
147 idle_timeout = atoi(property);
148 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800149
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400150 //create Idle Invalidator only when not disabled through property
151 if(idle_timeout != -1)
152 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800153
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400154 if(idleInvalidator == NULL) {
155 ALOGE("%s: failed to instantiate idleInvalidator object",
156 __FUNCTION__);
157 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530158 idleInvalidator->init(timeout_handler, ctx,
159 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800161 }
radhakrishnac9a67412013-09-25 17:40:42 +0530162
Saurabh Shah7c727642014-06-02 15:47:14 -0700163 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
164 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
165 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
166 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
radhakrishnac9a67412013-09-25 17:40:42 +0530167 sEnable4k2kYUVSplit = true;
168 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700169
170 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
171 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
172 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
173 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
174 HWC_DISPLAY_PRIMARY);
175 }
176
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700177 return true;
178}
179
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800180void MDPComp::reset(hwc_context_t *ctx) {
181 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700182 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800183 ctx->mOverlay->clear(mDpy);
184 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700185}
186
Raj Kamal4393eaa2014-06-06 13:45:20 +0530187void MDPComp::reset() {
188 sHandleTimeout = false;
189 mModeOn = false;
190}
191
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700192void MDPComp::timeout_handler(void *udata) {
193 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
194
195 if(!ctx) {
196 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
197 return;
198 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800199 Locker::Autolock _l(ctx->mDrawLock);
200 // Handle timeout event only if the previous composition is MDP or MIXED.
201 if(!sHandleTimeout) {
202 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
203 return;
204 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700205 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700206 ALOGE("%s: HWC proc not registered", __FUNCTION__);
207 return;
208 }
209 sIdleFallBack = true;
210 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700211 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212}
213
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 hwc_display_contents_1_t* list) {
216 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800217
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800218 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800219 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220 if(!mCurrentFrame.isFBComposed[index]) {
221 layerProp[index].mFlags |= HWC_MDPCOMP;
222 layer->compositionType = HWC_OVERLAY;
223 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800224 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700225 /* Drop the layer when its already present in FB OR when it lies
226 * outside frame's ROI */
227 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800228 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700229 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800230 }
231 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500233
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800234void MDPComp::setRedraw(hwc_context_t *ctx,
235 hwc_display_contents_1_t* list) {
236 mCurrentFrame.needsRedraw = false;
237 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
238 (list->flags & HWC_GEOMETRY_CHANGED) ||
239 isSkipPresent(ctx, mDpy)) {
240 mCurrentFrame.needsRedraw = true;
241 }
242}
243
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800244MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700245 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800247
Saurabh Shahaa236822013-04-24 18:07:26 -0700248void MDPComp::FrameInfo::reset(const int& numLayers) {
249 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800250 if(mdpToLayer[i].pipeInfo) {
251 delete mdpToLayer[i].pipeInfo;
252 mdpToLayer[i].pipeInfo = NULL;
253 //We dont own the rotator
254 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800255 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800256 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
258 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
259 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700260 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261
Saurabh Shahaa236822013-04-24 18:07:26 -0700262 layerCount = numLayers;
263 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700265 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800266 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800267}
268
Saurabh Shahaa236822013-04-24 18:07:26 -0700269void MDPComp::FrameInfo::map() {
270 // populate layer and MDP maps
271 int mdpIdx = 0;
272 for(int idx = 0; idx < layerCount; idx++) {
273 if(!isFBComposed[idx]) {
274 mdpToLayer[mdpIdx].listIndex = idx;
275 layerToMDP[idx] = mdpIdx++;
276 }
277 }
278}
279
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800280MDPComp::LayerCache::LayerCache() {
281 reset();
282}
283
284void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700285 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530286 memset(&isFBComposed, true, sizeof(isFBComposed));
287 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800288 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289}
290
291void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530292 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700293 for(int i = 0; i < numAppLayers; i++) {
294 hnd[i] = list->hwLayers[i].handle;
295 }
296}
297
298void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700299 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530300 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
301 memcpy(&drop, &curFrame.drop, sizeof(drop));
302}
303
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800304bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
305 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530306 if(layerCount != curFrame.layerCount)
307 return false;
308 for(int i = 0; i < curFrame.layerCount; i++) {
309 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
310 (curFrame.drop[i] != drop[i])) {
311 return false;
312 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800313 if(curFrame.isFBComposed[i] &&
314 (hnd[i] != list->hwLayers[i].handle)){
315 return false;
316 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530317 }
318 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800319}
320
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700321bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
322 private_handle_t *hnd = (private_handle_t *)layer->handle;
323 if((not isYuvBuffer(hnd) and has90Transform(layer)) or
324 (not isValidDimension(ctx,layer))
325 //More conditions here, SKIP, sRGB+Blend etc
326 ) {
327 return false;
328 }
329 return true;
330}
331
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530332bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800333 private_handle_t *hnd = (private_handle_t *)layer->handle;
334
335 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700336 if (layer->flags & HWC_COLOR_FILL) {
337 // Color layer
338 return true;
339 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800340 ALOGE("%s: layer handle is NULL", __FUNCTION__);
341 return false;
342 }
343
Naseer Ahmede850a802013-09-06 13:12:52 -0400344 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400345 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400346 return false;
347
Saurabh Shah62e1d732013-09-17 10:44:05 -0700348 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700350 int crop_w = crop.right - crop.left;
351 int crop_h = crop.bottom - crop.top;
352 int dst_w = dst.right - dst.left;
353 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800354 float w_scale = ((float)crop_w / (float)dst_w);
355 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700356
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 /* Workaround for MDP HW limitation in DSI command mode panels where
358 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
359 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530360 * There also is a HW limilation in MDP, minimum block size is 2x2
361 * Fallback to GPU if height is less than 2.
362 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800363 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800364 return false;
365
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800366 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700367 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700368 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800369 const float w_dscale = w_scale;
370 const float h_dscale = h_scale;
371
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800372 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700373
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800374 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700375 /* On targets that doesnt support Decimation (eg.,8x26)
376 * maximum downscale support is overlay pipe downscale.
377 */
378 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
379 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800380 return false;
381 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700382 // Decimation on macrotile format layers is not supported.
383 if(isTileRendered(hnd)) {
384 /* MDP can read maximum MAX_DISPLAY_DIM width.
385 * Bail out if
386 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
387 * 2. exceeds maximum downscale limit
388 */
389 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
390 w_dscale > maxMDPDownscale ||
391 h_dscale > maxMDPDownscale) {
392 return false;
393 }
394 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800395 return false;
396 }
397 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700398 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 return false;
400 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700401 }
402
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
404 const uint32_t upscale =
405 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
406 const float w_uscale = 1.0f / w_scale;
407 const float h_uscale = 1.0f / h_scale;
408
409 if(w_uscale > upscale || h_uscale > upscale)
410 return false;
411 }
412
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800413 return true;
414}
415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700417 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800418
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800419 if(!isEnabled()) {
420 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700421 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530422 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530423 qdutils::MDPVersion::getInstance().is8x16() ||
424 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800425 ctx->mVideoTransFlag &&
426 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700427 //1 Padding round to shift pipes across mixers
428 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
429 __FUNCTION__);
430 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800431 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800432 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800433 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700434 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530436 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
437 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700438 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700439 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700440 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800441}
442
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800443void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
444 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
445 fbRect = getIntersection(fbRect, roi);
446}
447
448/* 1) Identify layers that are not visible or lying outside the updating ROI and
449 * drop them from composition.
450 * 2) If we have a scaling layer which needs cropping against generated
451 * ROI, reset ROI to full resolution. */
452bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
453 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700454 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800455 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800456
457 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800458 if(!isValidRect(visibleRect)) {
459 mCurrentFrame.drop[i] = true;
460 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800461 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800462 }
463
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800466 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700467
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468 if(!isValidRect(res)) {
469 mCurrentFrame.drop[i] = true;
470 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800471 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472 /* Reset frame ROI when any layer which needs scaling also needs ROI
473 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800474 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800475 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700476 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
477 mCurrentFrame.dropCount = 0;
478 return false;
479 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800480
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800481 /* deduct any opaque region from visibleRect */
482 if (layer->blending == HWC_BLENDING_NONE)
483 visibleRect = deductRect(visibleRect, res);
484 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700485 }
486 return true;
487}
488
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800489/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
490 * are updating. If DirtyRegion is applicable, calculate it by accounting all
491 * the changing layer's dirtyRegion. */
492void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
493 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700494 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800495 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700496 return;
497
498 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800499 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
500 (int)ctx->dpyAttr[mDpy].yres};
501
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700502 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800503 hwc_layer_1_t* layer = &list->hwLayers[index];
504 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800505 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700506 hwc_rect_t dst = layer->displayFrame;
507 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800508
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800509#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800510 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700511 {
512 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
513 int x_off = dst.left - src.left;
514 int y_off = dst.top - src.top;
515 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
516 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800517#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800518
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800519 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700520 }
521 }
522
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800523 /* No layer is updating. Still SF wants a refresh.*/
524 if(!isValidRect(roi))
525 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800526
527 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800529
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800530 ctx->listStats[mDpy].lRoi = roi;
531 if(!validateAndApplyROI(ctx, list))
532 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700533
534 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
536 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
537}
538
539void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
540 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
541 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
542
543 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
544 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
545 fbRect = getUnion(l_fbRect, r_fbRect);
546}
547/* 1) Identify layers that are not visible or lying outside BOTH the updating
548 * ROI's and drop them from composition. If a layer is spanning across both
549 * the halves of the screen but needed by only ROI, the non-contributing
550 * half will not be programmed for MDP.
551 * 2) If we have a scaling layer which needs cropping against generated
552 * ROI, reset ROI to full resolution. */
553bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
554 hwc_display_contents_1_t* list) {
555
556 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
557
558 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
559 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
560
561 for(int i = numAppLayers - 1; i >= 0; i--){
562 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
563 {
564 mCurrentFrame.drop[i] = true;
565 mCurrentFrame.dropCount++;
566 continue;
567 }
568
569 const hwc_layer_1_t* layer = &list->hwLayers[i];
570 hwc_rect_t dstRect = layer->displayFrame;
571
572 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
573 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
574 hwc_rect_t res = getUnion(l_res, r_res);
575
576 if(!isValidRect(l_res) && !isValidRect(r_res)) {
577 mCurrentFrame.drop[i] = true;
578 mCurrentFrame.dropCount++;
579 } else {
580 /* Reset frame ROI when any layer which needs scaling also needs ROI
581 * cropping */
582 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
583 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
584 mCurrentFrame.dropCount = 0;
585 return false;
586 }
587
588 if (layer->blending == HWC_BLENDING_NONE) {
589 visibleRectL = deductRect(visibleRectL, l_res);
590 visibleRectR = deductRect(visibleRectR, r_res);
591 }
592 }
593 }
594 return true;
595}
596/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
597 * are updating. If DirtyRegion is applicable, calculate it by accounting all
598 * the changing layer's dirtyRegion. */
599void MDPCompSplit::generateROI(hwc_context_t *ctx,
600 hwc_display_contents_1_t* list) {
601 if(!canPartialUpdate(ctx, list))
602 return;
603
604 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
605 int lSplit = getLeftSplit(ctx, mDpy);
606
607 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
608 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
609
610 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
611 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
612
613 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
614 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
615
616 for(int index = 0; index < numAppLayers; index++ ) {
617 hwc_layer_1_t* layer = &list->hwLayers[index];
618 if ((mCachedFrame.hnd[index] != layer->handle) ||
619 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700620 hwc_rect_t dst = layer->displayFrame;
621 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800622
623#ifdef QCOM_BSP
624 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700625 {
626 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
627 int x_off = dst.left - src.left;
628 int y_off = dst.top - src.top;
629 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
630 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800631#endif
632
633 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
634 if(isValidRect(l_dst))
635 l_roi = getUnion(l_roi, l_dst);
636
637 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
638 if(isValidRect(r_dst))
639 r_roi = getUnion(r_roi, r_dst);
640 }
641 }
642
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700643 /* For panels that cannot accept commands in both the interfaces, we cannot
644 * send two ROI's (for each half). We merge them into single ROI and split
645 * them across lSplit for MDP mixer use. The ROI's will be merged again
646 * finally before udpating the panel in the driver. */
647 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
648 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
649 l_roi = getIntersection(temp_roi, l_frame);
650 r_roi = getIntersection(temp_roi, r_frame);
651 }
652
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800653 /* No layer is updating. Still SF wants a refresh. */
654 if(!isValidRect(l_roi) && !isValidRect(r_roi))
655 return;
656
657 l_roi = getSanitizeROI(l_roi, l_frame);
658 r_roi = getSanitizeROI(r_roi, r_frame);
659
660 ctx->listStats[mDpy].lRoi = l_roi;
661 ctx->listStats[mDpy].rRoi = r_roi;
662
663 if(!validateAndApplyROI(ctx, list))
664 resetROI(ctx, mDpy);
665
666 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
667 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
668 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
669 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
670 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
671 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700672}
673
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800674/* Checks for conditions where all the layers marked for MDP comp cannot be
675 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800676bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800677 hwc_display_contents_1_t* list){
678
Saurabh Shahaa236822013-04-24 18:07:26 -0700679 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800680 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800681
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700682 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700683 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
684 return false;
685 }
686
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800687 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700688 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
689 __FUNCTION__,
690 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800691 return false;
692 }
693
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800694 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
695 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
696 // Disable MDP comp on Secondary when the primary is highres panel and
697 // the secondary is a normal 1080p, because, MDP comp on secondary under
698 // in such usecase, decimation gets used for downscale and there will be
699 // a quality mismatch when there will be a fallback to GPU comp
700 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
701 __FUNCTION__);
702 return false;
703 }
704
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800705 // check for action safe flag and downscale mode which requires scaling.
706 if(ctx->dpyAttr[mDpy].mActionSafePresent
707 || ctx->dpyAttr[mDpy].mDownScaleMode) {
708 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
709 return false;
710 }
711
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800712 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800713 hwc_layer_1_t* layer = &list->hwLayers[i];
714 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800715
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700716 if(isYuvBuffer(hnd) && has90Transform(layer)) {
717 if(!canUseRotator(ctx, mDpy)) {
718 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
719 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700720 return false;
721 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800722 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530723
724 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
725 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700726 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530727 if(qdutils::MDPVersion::getInstance().is8x26() &&
728 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700729 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530730 (!isYuvBuffer(hnd)))
731 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800732 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700733
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700734 if(ctx->mAD->isDoable()) {
735 return false;
736 }
737
Saurabh Shahaa236822013-04-24 18:07:26 -0700738 //If all above hard conditions are met we can do full or partial MDP comp.
739 bool ret = false;
740 if(fullMDPComp(ctx, list)) {
741 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700742 } else if(fullMDPCompWithPTOR(ctx, list)) {
743 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700744 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700745 ret = true;
746 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530747
Saurabh Shahaa236822013-04-24 18:07:26 -0700748 return ret;
749}
750
751bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700752
753 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
754 return false;
755
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700756 //Will benefit presentation / secondary-only layer.
757 if((mDpy > HWC_DISPLAY_PRIMARY) &&
758 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
759 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
760 return false;
761 }
762
763 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
764 for(int i = 0; i < numAppLayers; i++) {
765 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700766 if(not mCurrentFrame.drop[i] and
767 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700768 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
769 return false;
770 }
771 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800772
Saurabh Shahaa236822013-04-24 18:07:26 -0700773 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700774 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
775 sizeof(mCurrentFrame.isFBComposed));
776 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
777 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700778
radhakrishnac9a67412013-09-25 17:40:42 +0530779 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800780 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530781 }
782
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800783 if(!postHeuristicsHandling(ctx, list)) {
784 ALOGD_IF(isDebug(), "post heuristic handling failed");
785 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700786 return false;
787 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700788 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
789 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700790 return true;
791}
792
Sushil Chauhandefd3522014-05-13 18:17:12 -0700793/* Full MDP Composition with Peripheral Tiny Overlap Removal.
794 * MDP bandwidth limitations can be avoided, if the overlap region
795 * covered by the smallest layer at a higher z-order, gets composed
796 * by Copybit on a render buffer, which can be queued to MDP.
797 */
798bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
799 hwc_display_contents_1_t* list) {
800
801 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
802 const int stagesForMDP = min(sMaxPipesPerMixer,
803 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
804
805 // Hard checks where we cannot use this mode
806 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
807 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
808 return false;
809 }
810
811 // Frame level checks
812 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
813 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
814 isSecurePresent(ctx, mDpy)) {
815 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
816 return false;
817 }
818
819 // Find overlap index
820 int overlapIdx = numAppLayers - 1;
821 uint32_t layerPixelCount, minPixelCount = 0;
822 for (int i = numAppLayers - 1; i >= 0; i--) {
823 hwc_layer_1_t* layer = &list->hwLayers[i];
824 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
825 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
826 if (!minPixelCount || (layerPixelCount < minPixelCount)) {
827 minPixelCount = layerPixelCount;
828 overlapIdx = i;
829 }
830 }
831
832 // No overlap
833 if (!overlapIdx)
834 return false;
835
836 /* We cannot use this composition mode, if:
837 1. A below layer needs scaling.
838 2. Overlap is not peripheral to display.
839 3. Overlap or a below layer has 90 degree transform.
840 4. Intersection of Overlap layer with a below layer is not valid.
841 5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
842 */
843
844 hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
845 if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
846 return false;
847
848 if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
849 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
850 return false;
851
852 for (int i = overlapIdx; i >= 0; i--) {
853 hwc_layer_1_t* layer = &list->hwLayers[i];
854 hwc_rect_t dispFrame = layer->displayFrame;
855
856 if (has90Transform(layer))
857 return false;
858
859 if (i < overlapIdx) {
860 if (needsScaling(layer) ||
861 !isValidRect(getIntersection(dispFrame, overlap)))
862 return false;
863 }
864 }
865
866 mOverlapIndex = overlapIdx;
867 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
868 ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
869 mOverlapIndex = -1;
870 return false;
871 }
872
873 hwc_rect_t sourceCrop[overlapIdx];
874 hwc_rect_t displayFrame[overlapIdx];
875
876 // Remove overlap from crop & displayFrame of below layers
877 for (int i = 0; i < overlapIdx; i++) {
878 hwc_layer_1_t* layer = &list->hwLayers[i];
879 displayFrame[i] = layer->displayFrame;
880 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
881
882 // Update layer attributes
883 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
884 hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
885 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
886 layer->transform);
887
888 layer->sourceCropf.left = (float)srcCrop.left;
889 layer->sourceCropf.top = (float)srcCrop.top;
890 layer->sourceCropf.right = (float)srcCrop.right;
891 layer->sourceCropf.bottom = (float)srcCrop.bottom;
892 }
893
894 mCurrentFrame.mdpCount = numAppLayers;
895 mCurrentFrame.fbCount = 0;
896 mCurrentFrame.fbZ = -1;
897
898 for (int j = 0; j < numAppLayers; j++)
899 mCurrentFrame.isFBComposed[j] = false;
900
901 bool result = postHeuristicsHandling(ctx, list);
902
903 // Restore layer attributes
904 for (int i = 0; i < overlapIdx; i++) {
905 hwc_layer_1_t* layer = &list->hwLayers[i];
906 layer->displayFrame = displayFrame[i];
907 layer->sourceCropf.left = (float)sourceCrop[i].left;
908 layer->sourceCropf.top = (float)sourceCrop[i].top;
909 layer->sourceCropf.right = (float)sourceCrop[i].right;
910 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
911 }
912
913 if (!result) {
914 mOverlapIndex = -1;
915 reset(ctx);
916 }
917
918 ALOGD_IF(isDebug(), "%s: Postheuristics %s!, Overlap index = %d",
919 __FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
920 return result;
921}
922
Saurabh Shahaa236822013-04-24 18:07:26 -0700923bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
924{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700925 if(!sEnableMixedMode) {
926 //Mixed mode is disabled. No need to even try caching.
927 return false;
928 }
929
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700930 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800931 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800932 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800933 cacheBasedComp(ctx, list);
934 } else {
935 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800936 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700937 }
938
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700939 return ret;
940}
941
942bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
943 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700944 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
945 return false;
946
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700947 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700948 mCurrentFrame.reset(numAppLayers);
949 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700950
951 //If an MDP marked layer is unsupported cannot do partial MDP Comp
952 for(int i = 0; i < numAppLayers; i++) {
953 if(!mCurrentFrame.isFBComposed[i]) {
954 hwc_layer_1_t* layer = &list->hwLayers[i];
955 if(not isSupportedForMDPComp(ctx, layer)) {
956 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
957 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800958 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700959 return false;
960 }
961 }
962 }
963
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700964 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530965 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700966 if(!ret) {
967 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800968 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700969 return false;
970 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700971
972 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700973
radhakrishnac9a67412013-09-25 17:40:42 +0530974 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800975 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530976 }
977
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700978 //Will benefit cases where a video has non-updating background.
979 if((mDpy > HWC_DISPLAY_PRIMARY) and
980 (mdpCount > MAX_SEC_LAYERS)) {
981 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800982 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700983 return false;
984 }
985
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800986 if(!postHeuristicsHandling(ctx, list)) {
987 ALOGD_IF(isDebug(), "post heuristic handling failed");
988 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700989 return false;
990 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700991 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
992 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700993
Saurabh Shahaa236822013-04-24 18:07:26 -0700994 return true;
995}
996
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800997bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -0800998 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700999 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1000 return false;
1001
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001002 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001003 return false;
1004 }
1005
Saurabh Shahb772ae32013-11-18 15:40:02 -08001006 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001007 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1008 const int stagesForMDP = min(sMaxPipesPerMixer,
1009 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001010
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001011 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1012 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1013 int lastMDPSupportedIndex = numAppLayers;
1014 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001015
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001016 //Find the minimum MDP batch size
1017 for(int i = 0; i < numAppLayers;i++) {
1018 if(mCurrentFrame.drop[i]) {
1019 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001020 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001021 }
1022 hwc_layer_1_t* layer = &list->hwLayers[i];
1023 if(not isSupportedForMDPComp(ctx, layer)) {
1024 lastMDPSupportedIndex = i;
1025 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1026 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001027 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001028 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001029 }
1030
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001031 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1032 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1033 mCurrentFrame.dropCount);
1034
1035 //Start at a point where the fb batch should at least have 2 layers, for
1036 //this mode to be justified.
1037 while(fbBatchSize < 2) {
1038 ++fbBatchSize;
1039 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001040 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001041
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001042 //If there are no layers for MDP, this mode doesnt make sense.
1043 if(mdpBatchSize < 1) {
1044 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1045 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001046 return false;
1047 }
1048
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001049 mCurrentFrame.reset(numAppLayers);
1050
1051 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1052 while(mdpBatchSize > 0) {
1053 //Mark layers for MDP comp
1054 int mdpBatchLeft = mdpBatchSize;
1055 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1056 if(mCurrentFrame.drop[i]) {
1057 continue;
1058 }
1059 mCurrentFrame.isFBComposed[i] = false;
1060 --mdpBatchLeft;
1061 }
1062
1063 mCurrentFrame.fbZ = mdpBatchSize;
1064 mCurrentFrame.fbCount = fbBatchSize;
1065 mCurrentFrame.mdpCount = mdpBatchSize;
1066
1067 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1068 __FUNCTION__, mdpBatchSize, fbBatchSize,
1069 mCurrentFrame.dropCount);
1070
1071 if(postHeuristicsHandling(ctx, list)) {
1072 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001073 __FUNCTION__);
1074 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1075 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001076 return true;
1077 }
1078
1079 reset(ctx);
1080 --mdpBatchSize;
1081 ++fbBatchSize;
1082 }
1083
1084 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001085}
1086
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001087bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301088 if(mDpy or isSecurePresent(ctx, mDpy) or
1089 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001090 return false;
1091 }
1092 return true;
1093}
1094
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001095bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1096 hwc_display_contents_1_t* list){
1097 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1098 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1099 mDpy ) {
1100 return false;
1101 }
1102 return true;
1103}
1104
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001105bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1106 hwc_display_contents_1_t* list) {
1107 const bool secureOnly = true;
1108 return videoOnlyComp(ctx, list, not secureOnly) or
1109 videoOnlyComp(ctx, list, secureOnly);
1110}
1111
1112bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001113 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001114 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1115 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001116 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001117
Saurabh Shahaa236822013-04-24 18:07:26 -07001118 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001119 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001120 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001121 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001122
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001123 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1124 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001125 return false;
1126 }
1127
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001128 /* Bail out if we are processing only secured video layers
1129 * and we dont have any */
1130 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001131 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001132 return false;
1133 }
1134
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001135 if(mCurrentFrame.fbCount)
1136 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001137
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001138 if(sEnable4k2kYUVSplit){
1139 adjustForSourceSplit(ctx, list);
1140 }
1141
1142 if(!postHeuristicsHandling(ctx, list)) {
1143 ALOGD_IF(isDebug(), "post heuristic handling failed");
1144 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001145 return false;
1146 }
1147
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001148 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1149 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001150 return true;
1151}
1152
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001153/* Checks for conditions where YUV layers cannot be bypassed */
1154bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001155 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001156 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001157 return false;
1158 }
1159
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001160 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
1161 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1162 return false;
1163 }
1164
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001165 if(isSecuring(ctx, layer)) {
1166 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1167 return false;
1168 }
1169
Saurabh Shah4fdde762013-04-30 18:47:33 -07001170 if(!isValidDimension(ctx, layer)) {
1171 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1172 __FUNCTION__);
1173 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001174 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001175
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001176 if(layer->planeAlpha < 0xFF) {
1177 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1178 in video only mode",
1179 __FUNCTION__);
1180 return false;
1181 }
1182
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001183 return true;
1184}
1185
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301186/* starts at fromIndex and check for each layer to find
1187 * if it it has overlapping with any Updating layer above it in zorder
1188 * till the end of the batch. returns true if it finds any intersection */
1189bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1190 int fromIndex, int toIndex) {
1191 for(int i = fromIndex; i < toIndex; i++) {
1192 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1193 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1194 return false;
1195 }
1196 }
1197 }
1198 return true;
1199}
1200
1201/* Checks if given layer at targetLayerIndex has any
1202 * intersection with all the updating layers in beween
1203 * fromIndex and toIndex. Returns true if it finds intersectiion */
1204bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1205 int fromIndex, int toIndex, int targetLayerIndex) {
1206 for(int i = fromIndex; i <= toIndex; i++) {
1207 if(!mCurrentFrame.isFBComposed[i]) {
1208 if(areLayersIntersecting(&list->hwLayers[i],
1209 &list->hwLayers[targetLayerIndex])) {
1210 return true;
1211 }
1212 }
1213 }
1214 return false;
1215}
1216
1217int MDPComp::getBatch(hwc_display_contents_1_t* list,
1218 int& maxBatchStart, int& maxBatchEnd,
1219 int& maxBatchCount) {
1220 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301221 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001222 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301223 while (i < mCurrentFrame.layerCount) {
1224 int batchCount = 0;
1225 int batchStart = i;
1226 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001227 /* Adjust batch Z order with the dropped layers so far */
1228 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301229 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301230 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301231 while(i < mCurrentFrame.layerCount) {
1232 if(!mCurrentFrame.isFBComposed[i]) {
1233 if(!batchCount) {
1234 i++;
1235 break;
1236 }
1237 updatingLayersAbove++;
1238 i++;
1239 continue;
1240 } else {
1241 if(mCurrentFrame.drop[i]) {
1242 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001243 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301244 continue;
1245 } else if(updatingLayersAbove <= 0) {
1246 batchCount++;
1247 batchEnd = i;
1248 i++;
1249 continue;
1250 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1251
1252 // We have a valid updating layer already. If layer-i not
1253 // have overlapping with all updating layers in between
1254 // batch-start and i, then we can add layer i to batch.
1255 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1256 batchCount++;
1257 batchEnd = i;
1258 i++;
1259 continue;
1260 } else if(canPushBatchToTop(list, batchStart, i)) {
1261 //If All the non-updating layers with in this batch
1262 //does not have intersection with the updating layers
1263 //above in z-order, then we can safely move the batch to
1264 //higher z-order. Increment fbZ as it is moving up.
1265 if( firstZReverseIndex < 0) {
1266 firstZReverseIndex = i;
1267 }
1268 batchCount++;
1269 batchEnd = i;
1270 fbZ += updatingLayersAbove;
1271 i++;
1272 updatingLayersAbove = 0;
1273 continue;
1274 } else {
1275 //both failed.start the loop again from here.
1276 if(firstZReverseIndex >= 0) {
1277 i = firstZReverseIndex;
1278 }
1279 break;
1280 }
1281 }
1282 }
1283 }
1284 if(batchCount > maxBatchCount) {
1285 maxBatchCount = batchCount;
1286 maxBatchStart = batchStart;
1287 maxBatchEnd = batchEnd;
1288 fbZOrder = fbZ;
1289 }
1290 }
1291 return fbZOrder;
1292}
1293
1294bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1295 hwc_display_contents_1_t* list) {
1296 /* Idea is to keep as many non-updating(cached) layers in FB and
1297 * send rest of them through MDP. This is done in 2 steps.
1298 * 1. Find the maximum contiguous batch of non-updating layers.
1299 * 2. See if we can improve this batch size for caching by adding
1300 * opaque layers around the batch, if they don't have
1301 * any overlapping with the updating layers in between.
1302 * NEVER mark an updating layer for caching.
1303 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001304
1305 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001306 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001307 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301308 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001309
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001310 /* Nothing is cached. No batching needed */
1311 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001312 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001313 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001314
1315 /* No MDP comp layers, try to use other comp modes */
1316 if(mCurrentFrame.mdpCount == 0) {
1317 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001318 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001319
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301320 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001321
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301322 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001323 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001324 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001325 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301326 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001327 if(!mCurrentFrame.drop[i]){
1328 //If an unsupported layer is being attempted to
1329 //be pulled out we should fail
1330 if(not isSupportedForMDPComp(ctx, layer)) {
1331 return false;
1332 }
1333 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001334 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001335 }
1336 }
1337
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301338 // update the frame data
1339 mCurrentFrame.fbZ = fbZ;
1340 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001341 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001342 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001343
1344 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301345 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001346
1347 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001348}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001349
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001350void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001351 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001352 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001353 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001354
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001355 for(int i = 0; i < numAppLayers; i++) {
1356 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001357 if(!mCurrentFrame.drop[i])
1358 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001359 mCurrentFrame.isFBComposed[i] = true;
1360 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001361 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001362 }
1363 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001364
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001365 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001366 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1367 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001368
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001369 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1370 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1371 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001372}
1373
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001374void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1375 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001376 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1377 for(int index = 0;index < nYuvCount; index++){
1378 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1379 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1380
1381 if(!isYUVDoable(ctx, layer)) {
1382 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1383 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1384 mCurrentFrame.fbCount++;
1385 }
1386 } else {
1387 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001388 private_handle_t *hnd = (private_handle_t *)layer->handle;
1389 if(!secureOnly || isSecureBuffer(hnd)) {
1390 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1391 mCurrentFrame.fbCount--;
1392 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001393 }
1394 }
1395 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001396
1397 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001398 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1399 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001400 mCurrentFrame.fbCount);
1401}
1402
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001403hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1404 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001405 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001406
1407 /* Update only the region of FB needed for composition */
1408 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1409 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1410 hwc_layer_1_t* layer = &list->hwLayers[i];
1411 hwc_rect_t dst = layer->displayFrame;
1412 fbRect = getUnion(fbRect, dst);
1413 }
1414 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001415 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001416 return fbRect;
1417}
1418
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001419bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1420 hwc_display_contents_1_t* list) {
1421
1422 //Capability checks
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301423 if(!resourceCheck()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001424 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1425 return false;
1426 }
1427
1428 //Limitations checks
1429 if(!hwLimitationsCheck(ctx, list)) {
1430 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1431 return false;
1432 }
1433
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001434 //Configure framebuffer first if applicable
1435 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001436 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001437 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1438 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001439 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1440 __FUNCTION__);
1441 return false;
1442 }
1443 }
1444
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001445 mCurrentFrame.map();
1446
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001447 if(!allocLayerPipes(ctx, list)) {
1448 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001449 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001450 }
1451
1452 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001453 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001454 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001455 int mdpIndex = mCurrentFrame.layerToMDP[index];
1456 hwc_layer_1_t* layer = &list->hwLayers[index];
1457
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301458 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1459 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1460 mdpNextZOrder++;
1461 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001462 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1463 cur_pipe->zOrder = mdpNextZOrder++;
1464
radhakrishnac9a67412013-09-25 17:40:42 +05301465 private_handle_t *hnd = (private_handle_t *)layer->handle;
1466 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1467 if(configure4k2kYuv(ctx, layer,
1468 mCurrentFrame.mdpToLayer[mdpIndex])
1469 != 0 ){
1470 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1471 for layer %d",__FUNCTION__, index);
1472 return false;
1473 }
1474 else{
1475 mdpNextZOrder++;
1476 }
1477 continue;
1478 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001479 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1480 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301481 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001482 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001483 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001484 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001485 }
1486
Saurabh Shaha36be922013-12-16 18:18:39 -08001487 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1488 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1489 ,__FUNCTION__, mDpy);
1490 return false;
1491 }
1492
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001493 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001494 return true;
1495}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001496
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301497bool MDPComp::resourceCheck() {
Saurabh Shah173f4242013-11-20 09:50:12 -08001498 const bool fbUsed = mCurrentFrame.fbCount;
1499 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1500 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1501 return false;
1502 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001503 return true;
1504}
1505
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301506bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1507 hwc_display_contents_1_t* list) {
1508
1509 //A-family hw limitation:
1510 //If a layer need alpha scaling, MDP can not support.
1511 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1512 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1513 if(!mCurrentFrame.isFBComposed[i] &&
1514 isAlphaScaled( &list->hwLayers[i])) {
1515 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1516 return false;
1517 }
1518 }
1519 }
1520
1521 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1522 //If multiple layers requires downscaling and also they are overlapping
1523 //fall back to GPU since MDSS can not handle it.
1524 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1525 qdutils::MDPVersion::getInstance().is8x26()) {
1526 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1527 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1528 if(!mCurrentFrame.isFBComposed[i] &&
1529 isDownscaleRequired(botLayer)) {
1530 //if layer-i is marked for MDP and needs downscaling
1531 //check if any MDP layer on top of i & overlaps with layer-i
1532 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1533 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1534 if(!mCurrentFrame.isFBComposed[j] &&
1535 isDownscaleRequired(topLayer)) {
1536 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1537 topLayer->displayFrame);
1538 if(isValidRect(r))
1539 return false;
1540 }
1541 }
1542 }
1543 }
1544 }
1545 return true;
1546}
1547
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001548int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001549 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001550 char property[PROPERTY_VALUE_MAX];
1551
Raj Kamal4393eaa2014-06-06 13:45:20 +05301552 if(!ctx || !list) {
1553 ALOGE("%s: Invalid context or list",__FUNCTION__);
1554 mCachedFrame.reset();
1555 return -1;
1556 }
1557
1558 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1559
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001560 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1561 int currentFlags = atoi(property);
1562 if(currentFlags != sSimulationFlags) {
1563 sSimulationFlags = currentFlags;
1564 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1565 sSimulationFlags, sSimulationFlags);
1566 }
1567 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001568 mOverlapIndex = -1;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001569
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301570 //Do not cache the information for next draw cycle.
1571 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1572 ALOGI("%s: Unsupported layer count for mdp composition",
1573 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001574 mCachedFrame.reset();
1575 return -1;
1576 }
1577
Saurabh Shahb39f8152013-08-22 10:21:44 -07001578 //reset old data
1579 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001580 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1581 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301582
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001583 // Detect the start of animation and fall back to GPU only once to cache
1584 // all the layers in FB and display FB content untill animation completes.
1585 if(ctx->listStats[mDpy].isDisplayAnimating) {
1586 mCurrentFrame.needsRedraw = false;
1587 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1588 mCurrentFrame.needsRedraw = true;
1589 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1590 }
1591 setMDPCompLayerFlags(ctx, list);
1592 mCachedFrame.updateCounts(mCurrentFrame);
1593 ret = -1;
1594 return ret;
1595 } else {
1596 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1597 }
1598
Saurabh Shahb39f8152013-08-22 10:21:44 -07001599 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001600 if(isFrameDoable(ctx)) {
1601 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001602
Raj Kamal4393eaa2014-06-06 13:45:20 +05301603 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1604 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001605 setMDPCompLayerFlags(ctx, list);
1606 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001607 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001608 reset(ctx);
1609 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1610 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001611 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001612 }
1613 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001614 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1615 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001616 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001617 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001618
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001620 ALOGD("GEOMETRY change: %d",
1621 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001622 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001623 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001624 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001625 }
1626
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001627 mCachedFrame.cacheAll(list);
1628 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001629 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001630}
1631
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001632bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301633
1634 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301635 int mdpIndex = mCurrentFrame.layerToMDP[index];
1636 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1637 info.pipeInfo = new MdpYUVPipeInfo;
1638 info.rot = NULL;
1639 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301640
1641 pipe_info.lIndex = ovutils::OV_INVALID;
1642 pipe_info.rIndex = ovutils::OV_INVALID;
1643
Saurabh Shahc62f3982014-03-05 14:28:26 -08001644 Overlay::PipeSpecs pipeSpecs;
1645 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1646 pipeSpecs.needsScaling = true;
1647 pipeSpecs.dpy = mDpy;
1648 pipeSpecs.fb = false;
1649
1650 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301651 if(pipe_info.lIndex == ovutils::OV_INVALID){
1652 bRet = false;
1653 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1654 __FUNCTION__);
1655 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001656 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301657 if(pipe_info.rIndex == ovutils::OV_INVALID){
1658 bRet = false;
1659 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1660 __FUNCTION__);
1661 }
1662 return bRet;
1663}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001664
1665int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1666 int fd = -1;
1667 if (mOverlapIndex != -1) {
1668 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
1669 if (fd < 0) {
1670 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
1671 mOverlapIndex = -1;
1672 }
1673 }
1674 return fd;
1675}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001676//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001677
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001678void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301679 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001680 //If 4k2k Yuv layer split is possible, and if
1681 //fbz is above 4k2k layer, increment fb zorder by 1
1682 //as we split 4k2k layer and increment zorder for right half
1683 //of the layer
1684 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301685 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1686 index++) {
1687 if(!mCurrentFrame.isFBComposed[index]) {
1688 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1689 mdpNextZOrder++;
1690 }
1691 mdpNextZOrder++;
1692 hwc_layer_1_t* layer = &list->hwLayers[index];
1693 private_handle_t *hnd = (private_handle_t *)layer->handle;
1694 if(is4kx2kYuvBuffer(hnd)) {
1695 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1696 mCurrentFrame.fbZ += 1;
1697 mdpNextZOrder++;
1698 //As we split 4kx2k yuv layer and program to 2 VG pipes
1699 //(if available) increase mdpcount by 1.
1700 mCurrentFrame.mdpCount++;
1701 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001702 }
1703 }
1704 }
radhakrishnac9a67412013-09-25 17:40:42 +05301705}
1706
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001707/*
1708 * Configures pipe(s) for MDP composition
1709 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001710int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001711 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001712 MdpPipeInfoNonSplit& mdp_info =
1713 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001714 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1715 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1716 eIsFg isFg = IS_FG_OFF;
1717 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001718
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001719 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1720 __FUNCTION__, layer, zOrder, dest);
1721
Saurabh Shah88e4d272013-09-03 13:31:29 -07001722 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001723 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001724}
1725
Saurabh Shah88e4d272013-09-03 13:31:29 -07001726bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001727 hwc_display_contents_1_t* list) {
1728 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001729
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001730 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001731
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001732 hwc_layer_1_t* layer = &list->hwLayers[index];
1733 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301734 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001735 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301736 continue;
1737 }
1738 }
1739
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001740 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001741 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001742 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001743 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001744 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001745
Saurabh Shahc62f3982014-03-05 14:28:26 -08001746 Overlay::PipeSpecs pipeSpecs;
1747 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1748 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1749 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1750 (qdutils::MDPVersion::getInstance().is8x26() and
1751 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1752 pipeSpecs.dpy = mDpy;
1753 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001754 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001755
Saurabh Shahc62f3982014-03-05 14:28:26 -08001756 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1757
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001758 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001759 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001760 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001761 }
1762 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001763 return true;
1764}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001765
radhakrishnac9a67412013-09-25 17:40:42 +05301766int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1767 PipeLayerPair& PipeLayerPair) {
1768 MdpYUVPipeInfo& mdp_info =
1769 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1770 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1771 eIsFg isFg = IS_FG_OFF;
1772 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1773 eDest lDest = mdp_info.lIndex;
1774 eDest rDest = mdp_info.rIndex;
1775
1776 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1777 lDest, rDest, &PipeLayerPair.rot);
1778}
1779
Saurabh Shah88e4d272013-09-03 13:31:29 -07001780bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001781
Raj Kamal4393eaa2014-06-06 13:45:20 +05301782 if(!isEnabled() or !mModeOn) {
1783 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301784 return true;
1785 }
1786
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001787 // Set the Handle timeout to true for MDP or MIXED composition.
1788 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1789 sHandleTimeout = true;
1790 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001791
1792 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001793 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001794
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001795 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1796 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001797 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001798 if(mCurrentFrame.isFBComposed[i]) continue;
1799
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001800 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001801 private_handle_t *hnd = (private_handle_t *)layer->handle;
1802 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001803 if (!(layer->flags & HWC_COLOR_FILL)) {
1804 ALOGE("%s handle null", __FUNCTION__);
1805 return false;
1806 }
1807 // No PLAY for Color layer
1808 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1809 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001810 }
1811
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001812 int mdpIndex = mCurrentFrame.layerToMDP[i];
1813
radhakrishnac9a67412013-09-25 17:40:42 +05301814 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1815 {
1816 MdpYUVPipeInfo& pipe_info =
1817 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1818 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1819 ovutils::eDest indexL = pipe_info.lIndex;
1820 ovutils::eDest indexR = pipe_info.rIndex;
1821 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301822 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301823 if(rot) {
1824 rot->queueBuffer(fd, offset);
1825 fd = rot->getDstMemId();
1826 offset = rot->getDstOffset();
1827 }
1828 if(indexL != ovutils::OV_INVALID) {
1829 ovutils::eDest destL = (ovutils::eDest)indexL;
1830 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1831 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1832 if (!ov.queueBuffer(fd, offset, destL)) {
1833 ALOGE("%s: queueBuffer failed for display:%d",
1834 __FUNCTION__, mDpy);
1835 return false;
1836 }
1837 }
1838
1839 if(indexR != ovutils::OV_INVALID) {
1840 ovutils::eDest destR = (ovutils::eDest)indexR;
1841 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1842 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1843 if (!ov.queueBuffer(fd, offset, destR)) {
1844 ALOGE("%s: queueBuffer failed for display:%d",
1845 __FUNCTION__, mDpy);
1846 return false;
1847 }
1848 }
1849 }
1850 else{
1851 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001852 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301853 ovutils::eDest dest = pipe_info.index;
1854 if(dest == ovutils::OV_INVALID) {
1855 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001856 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301857 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001858
radhakrishnac9a67412013-09-25 17:40:42 +05301859 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1860 continue;
1861 }
1862
Sushil Chauhandefd3522014-05-13 18:17:12 -07001863 if (!mDpy && (i == mOverlapIndex)) {
1864 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1865 }
1866
radhakrishnac9a67412013-09-25 17:40:42 +05301867 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1868 using pipe: %d", __FUNCTION__, layer,
1869 hnd, dest );
1870
1871 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301872 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301873
1874 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1875 if(rot) {
1876 if(!rot->queueBuffer(fd, offset))
1877 return false;
1878 fd = rot->getDstMemId();
1879 offset = rot->getDstOffset();
1880 }
1881
1882 if (!ov.queueBuffer(fd, offset, dest)) {
1883 ALOGE("%s: queueBuffer failed for display:%d ",
1884 __FUNCTION__, mDpy);
1885 return false;
1886 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001887 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001888
1889 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001890 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001891 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001892}
1893
Saurabh Shah88e4d272013-09-03 13:31:29 -07001894//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001895
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001896void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301897 hwc_display_contents_1_t* list){
1898 //if 4kx2k yuv layer is totally present in either in left half
1899 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301900 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301901 if(mCurrentFrame.fbZ >= 0) {
1902 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1903 index++) {
1904 if(!mCurrentFrame.isFBComposed[index]) {
1905 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1906 mdpNextZOrder++;
1907 }
1908 mdpNextZOrder++;
1909 hwc_layer_1_t* layer = &list->hwLayers[index];
1910 private_handle_t *hnd = (private_handle_t *)layer->handle;
1911 if(is4kx2kYuvBuffer(hnd)) {
1912 hwc_rect_t dst = layer->displayFrame;
1913 if((dst.left > lSplit) || (dst.right < lSplit)) {
1914 mCurrentFrame.mdpCount += 1;
1915 }
1916 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1917 mCurrentFrame.fbZ += 1;
1918 mdpNextZOrder++;
1919 }
1920 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001921 }
radhakrishnac9a67412013-09-25 17:40:42 +05301922 }
1923}
1924
Saurabh Shah88e4d272013-09-03 13:31:29 -07001925bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001926 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001927
Saurabh Shahc62f3982014-03-05 14:28:26 -08001928 const int lSplit = getLeftSplit(ctx, mDpy);
1929 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001930 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001931 pipe_info.lIndex = ovutils::OV_INVALID;
1932 pipe_info.rIndex = ovutils::OV_INVALID;
1933
Saurabh Shahc62f3982014-03-05 14:28:26 -08001934 Overlay::PipeSpecs pipeSpecs;
1935 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1936 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1937 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
1938 pipeSpecs.dpy = mDpy;
1939 pipeSpecs.mixer = Overlay::MIXER_LEFT;
1940 pipeSpecs.fb = false;
1941
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001942 // Acquire pipe only for the updating half
1943 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
1944 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
1945
1946 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001947 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001948 if(pipe_info.lIndex == ovutils::OV_INVALID)
1949 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001950 }
1951
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001952 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001953 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
1954 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001955 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001956 return false;
1957 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001958
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001959 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001960}
1961
Saurabh Shah88e4d272013-09-03 13:31:29 -07001962bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001963 hwc_display_contents_1_t* list) {
1964 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001965
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001966 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001967
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001968 hwc_layer_1_t* layer = &list->hwLayers[index];
1969 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301970 hwc_rect_t dst = layer->displayFrame;
1971 const int lSplit = getLeftSplit(ctx, mDpy);
1972 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1973 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001974 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301975 continue;
1976 }
1977 }
1978 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001979 int mdpIndex = mCurrentFrame.layerToMDP[index];
1980 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001981 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001982 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001983 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001984
Saurabh Shahc62f3982014-03-05 14:28:26 -08001985 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
1986 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
1987 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001988 return false;
1989 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001990 }
1991 return true;
1992}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001993
radhakrishnac9a67412013-09-25 17:40:42 +05301994int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1995 PipeLayerPair& PipeLayerPair) {
1996 const int lSplit = getLeftSplit(ctx, mDpy);
1997 hwc_rect_t dst = layer->displayFrame;
1998 if((dst.left > lSplit)||(dst.right < lSplit)){
1999 MdpYUVPipeInfo& mdp_info =
2000 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2001 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2002 eIsFg isFg = IS_FG_OFF;
2003 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2004 eDest lDest = mdp_info.lIndex;
2005 eDest rDest = mdp_info.rIndex;
2006
2007 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2008 lDest, rDest, &PipeLayerPair.rot);
2009 }
2010 else{
2011 return configure(ctx, layer, PipeLayerPair);
2012 }
2013}
2014
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002015/*
2016 * Configures pipe(s) for MDP composition
2017 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002018int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002019 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002020 MdpPipeInfoSplit& mdp_info =
2021 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002022 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2023 eIsFg isFg = IS_FG_OFF;
2024 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2025 eDest lDest = mdp_info.lIndex;
2026 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002027
2028 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2029 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2030
Saurabh Shah88e4d272013-09-03 13:31:29 -07002031 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002032 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002033}
2034
Saurabh Shah88e4d272013-09-03 13:31:29 -07002035bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002036
Raj Kamal4393eaa2014-06-06 13:45:20 +05302037 if(!isEnabled() or !mModeOn) {
2038 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302039 return true;
2040 }
2041
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002042 // Set the Handle timeout to true for MDP or MIXED composition.
2043 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2044 sHandleTimeout = true;
2045 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002046
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002047 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002048 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002049
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002050 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2051 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002052 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002053 if(mCurrentFrame.isFBComposed[i]) continue;
2054
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002055 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002056 private_handle_t *hnd = (private_handle_t *)layer->handle;
2057 if(!hnd) {
2058 ALOGE("%s handle null", __FUNCTION__);
2059 return false;
2060 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002061
2062 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2063 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002064 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002065
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002066 int mdpIndex = mCurrentFrame.layerToMDP[i];
2067
radhakrishnac9a67412013-09-25 17:40:42 +05302068 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2069 {
2070 MdpYUVPipeInfo& pipe_info =
2071 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2072 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2073 ovutils::eDest indexL = pipe_info.lIndex;
2074 ovutils::eDest indexR = pipe_info.rIndex;
2075 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302076 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302077 if(rot) {
2078 rot->queueBuffer(fd, offset);
2079 fd = rot->getDstMemId();
2080 offset = rot->getDstOffset();
2081 }
2082 if(indexL != ovutils::OV_INVALID) {
2083 ovutils::eDest destL = (ovutils::eDest)indexL;
2084 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2085 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2086 if (!ov.queueBuffer(fd, offset, destL)) {
2087 ALOGE("%s: queueBuffer failed for display:%d",
2088 __FUNCTION__, mDpy);
2089 return false;
2090 }
2091 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002092
radhakrishnac9a67412013-09-25 17:40:42 +05302093 if(indexR != ovutils::OV_INVALID) {
2094 ovutils::eDest destR = (ovutils::eDest)indexR;
2095 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2096 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2097 if (!ov.queueBuffer(fd, offset, destR)) {
2098 ALOGE("%s: queueBuffer failed for display:%d",
2099 __FUNCTION__, mDpy);
2100 return false;
2101 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002102 }
2103 }
radhakrishnac9a67412013-09-25 17:40:42 +05302104 else{
2105 MdpPipeInfoSplit& pipe_info =
2106 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2107 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002108
radhakrishnac9a67412013-09-25 17:40:42 +05302109 ovutils::eDest indexL = pipe_info.lIndex;
2110 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002111
Sushil Chauhandefd3522014-05-13 18:17:12 -07002112 if (!mDpy && (i == mOverlapIndex)) {
2113 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2114 }
2115
radhakrishnac9a67412013-09-25 17:40:42 +05302116 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302117 int offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302118
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002119 if(ctx->mAD->draw(ctx, fd, offset)) {
2120 fd = ctx->mAD->getDstFd();
2121 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002122 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002123
radhakrishnac9a67412013-09-25 17:40:42 +05302124 if(rot) {
2125 rot->queueBuffer(fd, offset);
2126 fd = rot->getDstMemId();
2127 offset = rot->getDstOffset();
2128 }
2129
2130 //************* play left mixer **********
2131 if(indexL != ovutils::OV_INVALID) {
2132 ovutils::eDest destL = (ovutils::eDest)indexL;
2133 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2134 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2135 if (!ov.queueBuffer(fd, offset, destL)) {
2136 ALOGE("%s: queueBuffer failed for left mixer",
2137 __FUNCTION__);
2138 return false;
2139 }
2140 }
2141
2142 //************* play right mixer **********
2143 if(indexR != ovutils::OV_INVALID) {
2144 ovutils::eDest destR = (ovutils::eDest)indexR;
2145 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2146 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2147 if (!ov.queueBuffer(fd, offset, destR)) {
2148 ALOGE("%s: queueBuffer failed for right mixer",
2149 __FUNCTION__);
2150 return false;
2151 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002152 }
2153 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002154
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002155 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2156 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002157
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002158 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002159}
Saurabh Shahab47c692014-02-12 18:45:57 -08002160
2161//================MDPCompSrcSplit==============================================
2162bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002163 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002164 private_handle_t *hnd = (private_handle_t *)layer->handle;
2165 hwc_rect_t dst = layer->displayFrame;
2166 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2167 pipe_info.lIndex = ovutils::OV_INVALID;
2168 pipe_info.rIndex = ovutils::OV_INVALID;
2169
2170 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2171 //should have a higher priority than the right one. Pipe priorities are
2172 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002173
Saurabh Shahc62f3982014-03-05 14:28:26 -08002174 Overlay::PipeSpecs pipeSpecs;
2175 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2176 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2177 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2178 pipeSpecs.dpy = mDpy;
2179 pipeSpecs.fb = false;
2180
Saurabh Shahab47c692014-02-12 18:45:57 -08002181 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002182 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002183 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002184 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002185 }
2186
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002187 /* Use 2 pipes IF
2188 a) Layer's crop width is > 2048 or
2189 b) Layer's dest width > 2048 or
2190 c) On primary, driver has indicated with caps to split always. This is
2191 based on an empirically derived value of panel height. Applied only
2192 if the layer's width is > mixer's width
2193 */
2194
2195 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2196 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2197 int lSplit = getLeftSplit(ctx, mDpy);
2198 int dstWidth = dst.right - dst.left;
2199 int cropWidth = crop.right - crop.left;
2200
2201 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2202 cropWidth > qdutils::MAX_DISPLAY_DIM or
2203 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002204 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002205 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002206 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002207 }
2208
2209 // Return values
2210 // 1 Left pipe is higher priority, do nothing.
2211 // 0 Pipes of same priority.
2212 //-1 Right pipe is of higher priority, needs swap.
2213 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2214 pipe_info.rIndex) == -1) {
2215 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002216 }
2217 }
2218
2219 return true;
2220}
2221
Saurabh Shahab47c692014-02-12 18:45:57 -08002222int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2223 PipeLayerPair& PipeLayerPair) {
2224 private_handle_t *hnd = (private_handle_t *)layer->handle;
2225 if(!hnd) {
2226 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2227 return -1;
2228 }
2229 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2230 MdpPipeInfoSplit& mdp_info =
2231 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2232 Rotator **rot = &PipeLayerPair.rot;
2233 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2234 eIsFg isFg = IS_FG_OFF;
2235 eDest lDest = mdp_info.lIndex;
2236 eDest rDest = mdp_info.rIndex;
2237 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2238 hwc_rect_t dst = layer->displayFrame;
2239 int transform = layer->transform;
2240 eTransform orient = static_cast<eTransform>(transform);
2241 const int downscale = 0;
2242 int rotFlags = ROT_FLAGS_NONE;
2243 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2244 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2245
2246 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2247 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2248
2249 // Handle R/B swap
2250 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2251 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2252 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2253 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2254 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2255 }
2256
Saurabh Shah97e2d802014-04-14 18:03:54 -07002257 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2258 setMdpFlags(layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002259
2260 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2261 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002262 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002263 }
2264
2265 if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
2266 (*rot) = ctx->mRotMgr->getNext();
2267 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002268 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002269 //If the video is using a single pipe, enable BWC
2270 if(rDest == OV_INVALID) {
2271 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2272 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002273 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002274 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002275 ALOGE("%s: configRotator failed!", __FUNCTION__);
2276 return -1;
2277 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002278 whf.format = (*rot)->getDstFormat();
2279 updateSource(orient, whf, crop);
2280 rotFlags |= ROT_PREROTATED;
2281 }
2282
2283 //If 2 pipes being used, divide layer into half, crop and dst
2284 hwc_rect_t cropL = crop;
2285 hwc_rect_t cropR = crop;
2286 hwc_rect_t dstL = dst;
2287 hwc_rect_t dstR = dst;
2288 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2289 cropL.right = (crop.right + crop.left) / 2;
2290 cropR.left = cropL.right;
2291 sanitizeSourceCrop(cropL, cropR, hnd);
2292
2293 //Swap crops on H flip since 2 pipes are being used
2294 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2295 hwc_rect_t tmp = cropL;
2296 cropL = cropR;
2297 cropR = tmp;
2298 }
2299
2300 dstL.right = (dst.right + dst.left) / 2;
2301 dstR.left = dstL.right;
2302 }
2303
2304 //For the mdp, since either we are pre-rotating or MDP does flips
2305 orient = OVERLAY_TRANSFORM_0;
2306 transform = 0;
2307
2308 //configure left pipe
2309 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002310 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002311 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2312 (ovutils::eBlending) getBlending(layer->blending));
2313
2314 if(configMdp(ctx->mOverlay, pargL, orient,
2315 cropL, dstL, metadata, lDest) < 0) {
2316 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2317 return -1;
2318 }
2319 }
2320
2321 //configure right pipe
2322 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002323 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002324 static_cast<eRotFlags>(rotFlags),
2325 layer->planeAlpha,
2326 (ovutils::eBlending) getBlending(layer->blending));
2327 if(configMdp(ctx->mOverlay, pargR, orient,
2328 cropR, dstR, metadata, rDest) < 0) {
2329 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2330 return -1;
2331 }
2332 }
2333
2334 return 0;
2335}
2336
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002337}; //namespace
2338