blob: 7c295025f5934ca39cd9624da2aa5c6e732bb045 [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 Shahe28a4022014-06-13 11:41:13 -0700350 bool rotated90 = (bool)layer->transform & HAL_TRANSFORM_ROT_90;
351 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
352 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700353 int dst_w = dst.right - dst.left;
354 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800355 float w_scale = ((float)crop_w / (float)dst_w);
356 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700357
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800358 /* Workaround for MDP HW limitation in DSI command mode panels where
359 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
360 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530361 * There also is a HW limilation in MDP, minimum block size is 2x2
362 * Fallback to GPU if height is less than 2.
363 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800364 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800365 return false;
366
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800367 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700368 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700369 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800370 const float w_dscale = w_scale;
371 const float h_dscale = h_scale;
372
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800373 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700374
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800375 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700376 /* On targets that doesnt support Decimation (eg.,8x26)
377 * maximum downscale support is overlay pipe downscale.
378 */
379 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
380 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800381 return false;
382 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700383 // Decimation on macrotile format layers is not supported.
384 if(isTileRendered(hnd)) {
385 /* MDP can read maximum MAX_DISPLAY_DIM width.
386 * Bail out if
387 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
388 * 2. exceeds maximum downscale limit
389 */
390 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
391 w_dscale > maxMDPDownscale ||
392 h_dscale > maxMDPDownscale) {
393 return false;
394 }
395 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800396 return false;
397 }
398 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700399 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700400 return false;
401 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700402 }
403
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800404 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
405 const uint32_t upscale =
406 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
407 const float w_uscale = 1.0f / w_scale;
408 const float h_uscale = 1.0f / h_scale;
409
410 if(w_uscale > upscale || h_uscale > upscale)
411 return false;
412 }
413
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800414 return true;
415}
416
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800417bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800419
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800420 if(!isEnabled()) {
421 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700422 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530423 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530424 qdutils::MDPVersion::getInstance().is8x16() ||
425 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800426 ctx->mVideoTransFlag &&
427 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700428 //1 Padding round to shift pipes across mixers
429 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
430 __FUNCTION__);
431 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800432 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800433 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800434 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530437 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
438 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700439 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700440 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700441 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800442}
443
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800444void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
445 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
446 fbRect = getIntersection(fbRect, roi);
447}
448
449/* 1) Identify layers that are not visible or lying outside the updating ROI and
450 * drop them from composition.
451 * 2) If we have a scaling layer which needs cropping against generated
452 * ROI, reset ROI to full resolution. */
453bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
454 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700455 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800456 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800457
458 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800459 if(!isValidRect(visibleRect)) {
460 mCurrentFrame.drop[i] = true;
461 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800462 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800463 }
464
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700466 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800467 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 if(!isValidRect(res)) {
470 mCurrentFrame.drop[i] = true;
471 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800472 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700473 /* Reset frame ROI when any layer which needs scaling also needs ROI
474 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800475 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800476 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700477 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
478 mCurrentFrame.dropCount = 0;
479 return false;
480 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800481
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800482 /* deduct any opaque region from visibleRect */
483 if (layer->blending == HWC_BLENDING_NONE)
484 visibleRect = deductRect(visibleRect, res);
485 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700486 }
487 return true;
488}
489
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800490/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
491 * are updating. If DirtyRegion is applicable, calculate it by accounting all
492 * the changing layer's dirtyRegion. */
493void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
494 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700495 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700497 return;
498
499 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800500 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
501 (int)ctx->dpyAttr[mDpy].yres};
502
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700503 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800504 hwc_layer_1_t* layer = &list->hwLayers[index];
505 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800506 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700507 hwc_rect_t dst = layer->displayFrame;
508 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800510#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800511 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700512 {
513 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
514 int x_off = dst.left - src.left;
515 int y_off = dst.top - src.top;
516 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
517 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800518#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800520 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700521 }
522 }
523
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800524 /* No layer is updating. Still SF wants a refresh.*/
525 if(!isValidRect(roi))
526 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800527
528 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800529 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800530
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800531 ctx->listStats[mDpy].lRoi = roi;
532 if(!validateAndApplyROI(ctx, list))
533 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534
535 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800536 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
537 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
538}
539
540void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
541 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
542 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
543
544 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
545 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
546 fbRect = getUnion(l_fbRect, r_fbRect);
547}
548/* 1) Identify layers that are not visible or lying outside BOTH the updating
549 * ROI's and drop them from composition. If a layer is spanning across both
550 * the halves of the screen but needed by only ROI, the non-contributing
551 * half will not be programmed for MDP.
552 * 2) If we have a scaling layer which needs cropping against generated
553 * ROI, reset ROI to full resolution. */
554bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
555 hwc_display_contents_1_t* list) {
556
557 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
558
559 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
560 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
561
562 for(int i = numAppLayers - 1; i >= 0; i--){
563 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
564 {
565 mCurrentFrame.drop[i] = true;
566 mCurrentFrame.dropCount++;
567 continue;
568 }
569
570 const hwc_layer_1_t* layer = &list->hwLayers[i];
571 hwc_rect_t dstRect = layer->displayFrame;
572
573 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
574 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
575 hwc_rect_t res = getUnion(l_res, r_res);
576
577 if(!isValidRect(l_res) && !isValidRect(r_res)) {
578 mCurrentFrame.drop[i] = true;
579 mCurrentFrame.dropCount++;
580 } else {
581 /* Reset frame ROI when any layer which needs scaling also needs ROI
582 * cropping */
583 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
584 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
585 mCurrentFrame.dropCount = 0;
586 return false;
587 }
588
589 if (layer->blending == HWC_BLENDING_NONE) {
590 visibleRectL = deductRect(visibleRectL, l_res);
591 visibleRectR = deductRect(visibleRectR, r_res);
592 }
593 }
594 }
595 return true;
596}
597/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
598 * are updating. If DirtyRegion is applicable, calculate it by accounting all
599 * the changing layer's dirtyRegion. */
600void MDPCompSplit::generateROI(hwc_context_t *ctx,
601 hwc_display_contents_1_t* list) {
602 if(!canPartialUpdate(ctx, list))
603 return;
604
605 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
606 int lSplit = getLeftSplit(ctx, mDpy);
607
608 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
609 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
610
611 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
612 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
613
614 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
615 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
616
617 for(int index = 0; index < numAppLayers; index++ ) {
618 hwc_layer_1_t* layer = &list->hwLayers[index];
619 if ((mCachedFrame.hnd[index] != layer->handle) ||
620 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700621 hwc_rect_t dst = layer->displayFrame;
622 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800623
624#ifdef QCOM_BSP
625 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700626 {
627 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
628 int x_off = dst.left - src.left;
629 int y_off = dst.top - src.top;
630 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
631 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800632#endif
633
634 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
635 if(isValidRect(l_dst))
636 l_roi = getUnion(l_roi, l_dst);
637
638 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
639 if(isValidRect(r_dst))
640 r_roi = getUnion(r_roi, r_dst);
641 }
642 }
643
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700644 /* For panels that cannot accept commands in both the interfaces, we cannot
645 * send two ROI's (for each half). We merge them into single ROI and split
646 * them across lSplit for MDP mixer use. The ROI's will be merged again
647 * finally before udpating the panel in the driver. */
648 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
649 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
650 l_roi = getIntersection(temp_roi, l_frame);
651 r_roi = getIntersection(temp_roi, r_frame);
652 }
653
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800654 /* No layer is updating. Still SF wants a refresh. */
655 if(!isValidRect(l_roi) && !isValidRect(r_roi))
656 return;
657
658 l_roi = getSanitizeROI(l_roi, l_frame);
659 r_roi = getSanitizeROI(r_roi, r_frame);
660
661 ctx->listStats[mDpy].lRoi = l_roi;
662 ctx->listStats[mDpy].rRoi = r_roi;
663
664 if(!validateAndApplyROI(ctx, list))
665 resetROI(ctx, mDpy);
666
667 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
668 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
669 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
670 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
671 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
672 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700673}
674
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800675/* Checks for conditions where all the layers marked for MDP comp cannot be
676 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800677bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800678 hwc_display_contents_1_t* list){
679
Saurabh Shahaa236822013-04-24 18:07:26 -0700680 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800681 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800682
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700683 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700684 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
685 return false;
686 }
687
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800688 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700689 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
690 __FUNCTION__,
691 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800692 return false;
693 }
694
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800695 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
696 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
697 // Disable MDP comp on Secondary when the primary is highres panel and
698 // the secondary is a normal 1080p, because, MDP comp on secondary under
699 // in such usecase, decimation gets used for downscale and there will be
700 // a quality mismatch when there will be a fallback to GPU comp
701 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
702 __FUNCTION__);
703 return false;
704 }
705
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800706 // check for action safe flag and downscale mode which requires scaling.
707 if(ctx->dpyAttr[mDpy].mActionSafePresent
708 || ctx->dpyAttr[mDpy].mDownScaleMode) {
709 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
710 return false;
711 }
712
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800713 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800714 hwc_layer_1_t* layer = &list->hwLayers[i];
715 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800716
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700717 if(isYuvBuffer(hnd) && has90Transform(layer)) {
718 if(!canUseRotator(ctx, mDpy)) {
719 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
720 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700721 return false;
722 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800723 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530724
725 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
726 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700727 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530728 if(qdutils::MDPVersion::getInstance().is8x26() &&
729 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700730 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530731 (!isYuvBuffer(hnd)))
732 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800733 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700734
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700735 if(ctx->mAD->isDoable()) {
736 return false;
737 }
738
Saurabh Shahaa236822013-04-24 18:07:26 -0700739 //If all above hard conditions are met we can do full or partial MDP comp.
740 bool ret = false;
741 if(fullMDPComp(ctx, list)) {
742 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700743 } else if(fullMDPCompWithPTOR(ctx, list)) {
744 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700745 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 ret = true;
747 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530748
Saurabh Shahaa236822013-04-24 18:07:26 -0700749 return ret;
750}
751
752bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700753
754 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
755 return false;
756
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700757 //Will benefit presentation / secondary-only layer.
758 if((mDpy > HWC_DISPLAY_PRIMARY) &&
759 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
760 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
761 return false;
762 }
763
764 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
765 for(int i = 0; i < numAppLayers; i++) {
766 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700767 if(not mCurrentFrame.drop[i] and
768 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700769 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
770 return false;
771 }
772 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800773
Saurabh Shahaa236822013-04-24 18:07:26 -0700774 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700775 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
776 sizeof(mCurrentFrame.isFBComposed));
777 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
778 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700779
radhakrishnac9a67412013-09-25 17:40:42 +0530780 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800781 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530782 }
783
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800784 if(!postHeuristicsHandling(ctx, list)) {
785 ALOGD_IF(isDebug(), "post heuristic handling failed");
786 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700787 return false;
788 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700789 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
790 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700791 return true;
792}
793
Sushil Chauhandefd3522014-05-13 18:17:12 -0700794/* Full MDP Composition with Peripheral Tiny Overlap Removal.
795 * MDP bandwidth limitations can be avoided, if the overlap region
796 * covered by the smallest layer at a higher z-order, gets composed
797 * by Copybit on a render buffer, which can be queued to MDP.
798 */
799bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
800 hwc_display_contents_1_t* list) {
801
802 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
803 const int stagesForMDP = min(sMaxPipesPerMixer,
804 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
805
806 // Hard checks where we cannot use this mode
807 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
808 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
809 return false;
810 }
811
812 // Frame level checks
813 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
814 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
815 isSecurePresent(ctx, mDpy)) {
816 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
817 return false;
818 }
819
820 // Find overlap index
821 int overlapIdx = numAppLayers - 1;
822 uint32_t layerPixelCount, minPixelCount = 0;
823 for (int i = numAppLayers - 1; i >= 0; i--) {
824 hwc_layer_1_t* layer = &list->hwLayers[i];
825 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
826 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
827 if (!minPixelCount || (layerPixelCount < minPixelCount)) {
828 minPixelCount = layerPixelCount;
829 overlapIdx = i;
830 }
831 }
832
833 // No overlap
834 if (!overlapIdx)
835 return false;
836
837 /* We cannot use this composition mode, if:
838 1. A below layer needs scaling.
839 2. Overlap is not peripheral to display.
840 3. Overlap or a below layer has 90 degree transform.
841 4. Intersection of Overlap layer with a below layer is not valid.
842 5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
843 */
844
845 hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
846 if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
847 return false;
848
849 if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
850 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
851 return false;
852
853 for (int i = overlapIdx; i >= 0; i--) {
854 hwc_layer_1_t* layer = &list->hwLayers[i];
855 hwc_rect_t dispFrame = layer->displayFrame;
856
857 if (has90Transform(layer))
858 return false;
859
860 if (i < overlapIdx) {
861 if (needsScaling(layer) ||
862 !isValidRect(getIntersection(dispFrame, overlap)))
863 return false;
864 }
865 }
866
867 mOverlapIndex = overlapIdx;
868 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
869 ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
870 mOverlapIndex = -1;
871 return false;
872 }
873
874 hwc_rect_t sourceCrop[overlapIdx];
875 hwc_rect_t displayFrame[overlapIdx];
876
877 // Remove overlap from crop & displayFrame of below layers
878 for (int i = 0; i < overlapIdx; i++) {
879 hwc_layer_1_t* layer = &list->hwLayers[i];
880 displayFrame[i] = layer->displayFrame;
881 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
882
883 // Update layer attributes
884 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
885 hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
886 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
887 layer->transform);
888
889 layer->sourceCropf.left = (float)srcCrop.left;
890 layer->sourceCropf.top = (float)srcCrop.top;
891 layer->sourceCropf.right = (float)srcCrop.right;
892 layer->sourceCropf.bottom = (float)srcCrop.bottom;
893 }
894
895 mCurrentFrame.mdpCount = numAppLayers;
896 mCurrentFrame.fbCount = 0;
897 mCurrentFrame.fbZ = -1;
898
899 for (int j = 0; j < numAppLayers; j++)
900 mCurrentFrame.isFBComposed[j] = false;
901
902 bool result = postHeuristicsHandling(ctx, list);
903
904 // Restore layer attributes
905 for (int i = 0; i < overlapIdx; i++) {
906 hwc_layer_1_t* layer = &list->hwLayers[i];
907 layer->displayFrame = displayFrame[i];
908 layer->sourceCropf.left = (float)sourceCrop[i].left;
909 layer->sourceCropf.top = (float)sourceCrop[i].top;
910 layer->sourceCropf.right = (float)sourceCrop[i].right;
911 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
912 }
913
914 if (!result) {
915 mOverlapIndex = -1;
916 reset(ctx);
917 }
918
919 ALOGD_IF(isDebug(), "%s: Postheuristics %s!, Overlap index = %d",
920 __FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
921 return result;
922}
923
Saurabh Shahaa236822013-04-24 18:07:26 -0700924bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
925{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700926 if(!sEnableMixedMode) {
927 //Mixed mode is disabled. No need to even try caching.
928 return false;
929 }
930
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700931 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800932 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800933 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800934 cacheBasedComp(ctx, list);
935 } else {
936 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800937 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700938 }
939
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700940 return ret;
941}
942
943bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
944 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700945 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
946 return false;
947
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700948 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700949 mCurrentFrame.reset(numAppLayers);
950 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700951
952 //If an MDP marked layer is unsupported cannot do partial MDP Comp
953 for(int i = 0; i < numAppLayers; i++) {
954 if(!mCurrentFrame.isFBComposed[i]) {
955 hwc_layer_1_t* layer = &list->hwLayers[i];
956 if(not isSupportedForMDPComp(ctx, layer)) {
957 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
958 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800959 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700960 return false;
961 }
962 }
963 }
964
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700965 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530966 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700967 if(!ret) {
968 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800969 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700970 return false;
971 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700972
973 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700974
radhakrishnac9a67412013-09-25 17:40:42 +0530975 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800976 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530977 }
978
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700979 //Will benefit cases where a video has non-updating background.
980 if((mDpy > HWC_DISPLAY_PRIMARY) and
981 (mdpCount > MAX_SEC_LAYERS)) {
982 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800983 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700984 return false;
985 }
986
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800987 if(!postHeuristicsHandling(ctx, list)) {
988 ALOGD_IF(isDebug(), "post heuristic handling failed");
989 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700990 return false;
991 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700992 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
993 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700994
Saurabh Shahaa236822013-04-24 18:07:26 -0700995 return true;
996}
997
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800998bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -0800999 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001000 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1001 return false;
1002
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001003 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001004 return false;
1005 }
1006
Saurabh Shahb772ae32013-11-18 15:40:02 -08001007 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001008 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1009 const int stagesForMDP = min(sMaxPipesPerMixer,
1010 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001011
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001012 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1013 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1014 int lastMDPSupportedIndex = numAppLayers;
1015 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001016
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001017 //Find the minimum MDP batch size
1018 for(int i = 0; i < numAppLayers;i++) {
1019 if(mCurrentFrame.drop[i]) {
1020 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001021 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001022 }
1023 hwc_layer_1_t* layer = &list->hwLayers[i];
1024 if(not isSupportedForMDPComp(ctx, layer)) {
1025 lastMDPSupportedIndex = i;
1026 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1027 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001028 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001029 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001030 }
1031
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001032 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1033 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1034 mCurrentFrame.dropCount);
1035
1036 //Start at a point where the fb batch should at least have 2 layers, for
1037 //this mode to be justified.
1038 while(fbBatchSize < 2) {
1039 ++fbBatchSize;
1040 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001041 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001042
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001043 //If there are no layers for MDP, this mode doesnt make sense.
1044 if(mdpBatchSize < 1) {
1045 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1046 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001047 return false;
1048 }
1049
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001050 mCurrentFrame.reset(numAppLayers);
1051
1052 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1053 while(mdpBatchSize > 0) {
1054 //Mark layers for MDP comp
1055 int mdpBatchLeft = mdpBatchSize;
1056 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1057 if(mCurrentFrame.drop[i]) {
1058 continue;
1059 }
1060 mCurrentFrame.isFBComposed[i] = false;
1061 --mdpBatchLeft;
1062 }
1063
1064 mCurrentFrame.fbZ = mdpBatchSize;
1065 mCurrentFrame.fbCount = fbBatchSize;
1066 mCurrentFrame.mdpCount = mdpBatchSize;
1067
1068 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1069 __FUNCTION__, mdpBatchSize, fbBatchSize,
1070 mCurrentFrame.dropCount);
1071
1072 if(postHeuristicsHandling(ctx, list)) {
1073 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001074 __FUNCTION__);
1075 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1076 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001077 return true;
1078 }
1079
1080 reset(ctx);
1081 --mdpBatchSize;
1082 ++fbBatchSize;
1083 }
1084
1085 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001086}
1087
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001088bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301089 if(mDpy or isSecurePresent(ctx, mDpy) or
1090 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001091 return false;
1092 }
1093 return true;
1094}
1095
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001096bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1097 hwc_display_contents_1_t* list){
1098 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1099 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1100 mDpy ) {
1101 return false;
1102 }
1103 return true;
1104}
1105
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001106bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1107 hwc_display_contents_1_t* list) {
1108 const bool secureOnly = true;
1109 return videoOnlyComp(ctx, list, not secureOnly) or
1110 videoOnlyComp(ctx, list, secureOnly);
1111}
1112
1113bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001114 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001115 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1116 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001117 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001118
Saurabh Shahaa236822013-04-24 18:07:26 -07001119 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001120 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001121 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001122 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001123
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001124 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1125 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001126 return false;
1127 }
1128
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001129 /* Bail out if we are processing only secured video layers
1130 * and we dont have any */
1131 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001132 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001133 return false;
1134 }
1135
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001136 if(mCurrentFrame.fbCount)
1137 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001138
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001139 if(sEnable4k2kYUVSplit){
1140 adjustForSourceSplit(ctx, list);
1141 }
1142
1143 if(!postHeuristicsHandling(ctx, list)) {
1144 ALOGD_IF(isDebug(), "post heuristic handling failed");
1145 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001146 return false;
1147 }
1148
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001149 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1150 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001151 return true;
1152}
1153
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001154/* Checks for conditions where YUV layers cannot be bypassed */
1155bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001156 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001157 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001158 return false;
1159 }
1160
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001161 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
1162 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1163 return false;
1164 }
1165
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001166 if(isSecuring(ctx, layer)) {
1167 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1168 return false;
1169 }
1170
Saurabh Shah4fdde762013-04-30 18:47:33 -07001171 if(!isValidDimension(ctx, layer)) {
1172 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1173 __FUNCTION__);
1174 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001175 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001176
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001177 if(layer->planeAlpha < 0xFF) {
1178 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1179 in video only mode",
1180 __FUNCTION__);
1181 return false;
1182 }
1183
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001184 return true;
1185}
1186
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301187/* starts at fromIndex and check for each layer to find
1188 * if it it has overlapping with any Updating layer above it in zorder
1189 * till the end of the batch. returns true if it finds any intersection */
1190bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1191 int fromIndex, int toIndex) {
1192 for(int i = fromIndex; i < toIndex; i++) {
1193 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1194 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1195 return false;
1196 }
1197 }
1198 }
1199 return true;
1200}
1201
1202/* Checks if given layer at targetLayerIndex has any
1203 * intersection with all the updating layers in beween
1204 * fromIndex and toIndex. Returns true if it finds intersectiion */
1205bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1206 int fromIndex, int toIndex, int targetLayerIndex) {
1207 for(int i = fromIndex; i <= toIndex; i++) {
1208 if(!mCurrentFrame.isFBComposed[i]) {
1209 if(areLayersIntersecting(&list->hwLayers[i],
1210 &list->hwLayers[targetLayerIndex])) {
1211 return true;
1212 }
1213 }
1214 }
1215 return false;
1216}
1217
1218int MDPComp::getBatch(hwc_display_contents_1_t* list,
1219 int& maxBatchStart, int& maxBatchEnd,
1220 int& maxBatchCount) {
1221 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301222 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001223 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301224 while (i < mCurrentFrame.layerCount) {
1225 int batchCount = 0;
1226 int batchStart = i;
1227 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001228 /* Adjust batch Z order with the dropped layers so far */
1229 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301230 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301231 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301232 while(i < mCurrentFrame.layerCount) {
1233 if(!mCurrentFrame.isFBComposed[i]) {
1234 if(!batchCount) {
1235 i++;
1236 break;
1237 }
1238 updatingLayersAbove++;
1239 i++;
1240 continue;
1241 } else {
1242 if(mCurrentFrame.drop[i]) {
1243 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001244 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301245 continue;
1246 } else if(updatingLayersAbove <= 0) {
1247 batchCount++;
1248 batchEnd = i;
1249 i++;
1250 continue;
1251 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1252
1253 // We have a valid updating layer already. If layer-i not
1254 // have overlapping with all updating layers in between
1255 // batch-start and i, then we can add layer i to batch.
1256 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1257 batchCount++;
1258 batchEnd = i;
1259 i++;
1260 continue;
1261 } else if(canPushBatchToTop(list, batchStart, i)) {
1262 //If All the non-updating layers with in this batch
1263 //does not have intersection with the updating layers
1264 //above in z-order, then we can safely move the batch to
1265 //higher z-order. Increment fbZ as it is moving up.
1266 if( firstZReverseIndex < 0) {
1267 firstZReverseIndex = i;
1268 }
1269 batchCount++;
1270 batchEnd = i;
1271 fbZ += updatingLayersAbove;
1272 i++;
1273 updatingLayersAbove = 0;
1274 continue;
1275 } else {
1276 //both failed.start the loop again from here.
1277 if(firstZReverseIndex >= 0) {
1278 i = firstZReverseIndex;
1279 }
1280 break;
1281 }
1282 }
1283 }
1284 }
1285 if(batchCount > maxBatchCount) {
1286 maxBatchCount = batchCount;
1287 maxBatchStart = batchStart;
1288 maxBatchEnd = batchEnd;
1289 fbZOrder = fbZ;
1290 }
1291 }
1292 return fbZOrder;
1293}
1294
1295bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1296 hwc_display_contents_1_t* list) {
1297 /* Idea is to keep as many non-updating(cached) layers in FB and
1298 * send rest of them through MDP. This is done in 2 steps.
1299 * 1. Find the maximum contiguous batch of non-updating layers.
1300 * 2. See if we can improve this batch size for caching by adding
1301 * opaque layers around the batch, if they don't have
1302 * any overlapping with the updating layers in between.
1303 * NEVER mark an updating layer for caching.
1304 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001305
1306 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001307 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001308 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301309 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001310
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001311 /* Nothing is cached. No batching needed */
1312 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001313 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001314 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001315
1316 /* No MDP comp layers, try to use other comp modes */
1317 if(mCurrentFrame.mdpCount == 0) {
1318 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001319 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001320
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301321 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001322
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301323 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001324 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001325 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001326 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301327 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001328 if(!mCurrentFrame.drop[i]){
1329 //If an unsupported layer is being attempted to
1330 //be pulled out we should fail
1331 if(not isSupportedForMDPComp(ctx, layer)) {
1332 return false;
1333 }
1334 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001335 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001336 }
1337 }
1338
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301339 // update the frame data
1340 mCurrentFrame.fbZ = fbZ;
1341 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001342 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001343 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001344
1345 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301346 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001347
1348 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001349}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001350
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001351void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001352 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001353 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001354 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001355
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001356 for(int i = 0; i < numAppLayers; i++) {
1357 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001358 if(!mCurrentFrame.drop[i])
1359 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001360 mCurrentFrame.isFBComposed[i] = true;
1361 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001362 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001363 }
1364 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001365
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001366 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001367 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1368 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001369
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001370 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1371 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1372 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001373}
1374
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001375void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1376 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001377 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1378 for(int index = 0;index < nYuvCount; index++){
1379 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1380 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1381
1382 if(!isYUVDoable(ctx, layer)) {
1383 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1384 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1385 mCurrentFrame.fbCount++;
1386 }
1387 } else {
1388 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001389 private_handle_t *hnd = (private_handle_t *)layer->handle;
1390 if(!secureOnly || isSecureBuffer(hnd)) {
1391 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1392 mCurrentFrame.fbCount--;
1393 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001394 }
1395 }
1396 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001397
1398 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001399 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1400 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001401 mCurrentFrame.fbCount);
1402}
1403
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001404hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1405 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001406 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001407
1408 /* Update only the region of FB needed for composition */
1409 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1410 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1411 hwc_layer_1_t* layer = &list->hwLayers[i];
1412 hwc_rect_t dst = layer->displayFrame;
1413 fbRect = getUnion(fbRect, dst);
1414 }
1415 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001416 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001417 return fbRect;
1418}
1419
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001420bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1421 hwc_display_contents_1_t* list) {
1422
1423 //Capability checks
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301424 if(!resourceCheck()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001425 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1426 return false;
1427 }
1428
1429 //Limitations checks
1430 if(!hwLimitationsCheck(ctx, list)) {
1431 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1432 return false;
1433 }
1434
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001435 //Configure framebuffer first if applicable
1436 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001437 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001438 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1439 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001440 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1441 __FUNCTION__);
1442 return false;
1443 }
1444 }
1445
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001446 mCurrentFrame.map();
1447
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001448 if(!allocLayerPipes(ctx, list)) {
1449 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001450 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001451 }
1452
1453 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001454 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001455 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001456 int mdpIndex = mCurrentFrame.layerToMDP[index];
1457 hwc_layer_1_t* layer = &list->hwLayers[index];
1458
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301459 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1460 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1461 mdpNextZOrder++;
1462 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001463 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1464 cur_pipe->zOrder = mdpNextZOrder++;
1465
radhakrishnac9a67412013-09-25 17:40:42 +05301466 private_handle_t *hnd = (private_handle_t *)layer->handle;
1467 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1468 if(configure4k2kYuv(ctx, layer,
1469 mCurrentFrame.mdpToLayer[mdpIndex])
1470 != 0 ){
1471 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1472 for layer %d",__FUNCTION__, index);
1473 return false;
1474 }
1475 else{
1476 mdpNextZOrder++;
1477 }
1478 continue;
1479 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001480 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1481 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301482 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001483 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001484 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001485 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001486 }
1487
Saurabh Shaha36be922013-12-16 18:18:39 -08001488 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1489 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1490 ,__FUNCTION__, mDpy);
1491 return false;
1492 }
1493
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001494 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001495 return true;
1496}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001497
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301498bool MDPComp::resourceCheck() {
Saurabh Shah173f4242013-11-20 09:50:12 -08001499 const bool fbUsed = mCurrentFrame.fbCount;
1500 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1501 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1502 return false;
1503 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001504 return true;
1505}
1506
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301507bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1508 hwc_display_contents_1_t* list) {
1509
1510 //A-family hw limitation:
1511 //If a layer need alpha scaling, MDP can not support.
1512 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1513 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1514 if(!mCurrentFrame.isFBComposed[i] &&
1515 isAlphaScaled( &list->hwLayers[i])) {
1516 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1517 return false;
1518 }
1519 }
1520 }
1521
1522 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1523 //If multiple layers requires downscaling and also they are overlapping
1524 //fall back to GPU since MDSS can not handle it.
1525 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1526 qdutils::MDPVersion::getInstance().is8x26()) {
1527 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1528 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1529 if(!mCurrentFrame.isFBComposed[i] &&
1530 isDownscaleRequired(botLayer)) {
1531 //if layer-i is marked for MDP and needs downscaling
1532 //check if any MDP layer on top of i & overlaps with layer-i
1533 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1534 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1535 if(!mCurrentFrame.isFBComposed[j] &&
1536 isDownscaleRequired(topLayer)) {
1537 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1538 topLayer->displayFrame);
1539 if(isValidRect(r))
1540 return false;
1541 }
1542 }
1543 }
1544 }
1545 }
1546 return true;
1547}
1548
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001549int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001550 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001551 char property[PROPERTY_VALUE_MAX];
1552
Raj Kamal4393eaa2014-06-06 13:45:20 +05301553 if(!ctx || !list) {
1554 ALOGE("%s: Invalid context or list",__FUNCTION__);
1555 mCachedFrame.reset();
1556 return -1;
1557 }
1558
1559 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1560
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001561 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1562 int currentFlags = atoi(property);
1563 if(currentFlags != sSimulationFlags) {
1564 sSimulationFlags = currentFlags;
1565 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1566 sSimulationFlags, sSimulationFlags);
1567 }
1568 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001569 mOverlapIndex = -1;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001570
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301571 //Do not cache the information for next draw cycle.
1572 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1573 ALOGI("%s: Unsupported layer count for mdp composition",
1574 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001575 mCachedFrame.reset();
1576 return -1;
1577 }
1578
Saurabh Shahb39f8152013-08-22 10:21:44 -07001579 //reset old data
1580 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001581 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1582 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301583
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001584 // Detect the start of animation and fall back to GPU only once to cache
1585 // all the layers in FB and display FB content untill animation completes.
1586 if(ctx->listStats[mDpy].isDisplayAnimating) {
1587 mCurrentFrame.needsRedraw = false;
1588 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1589 mCurrentFrame.needsRedraw = true;
1590 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1591 }
1592 setMDPCompLayerFlags(ctx, list);
1593 mCachedFrame.updateCounts(mCurrentFrame);
1594 ret = -1;
1595 return ret;
1596 } else {
1597 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1598 }
1599
Saurabh Shahb39f8152013-08-22 10:21:44 -07001600 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001601 if(isFrameDoable(ctx)) {
1602 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001603
Raj Kamal4393eaa2014-06-06 13:45:20 +05301604 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1605 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001606 setMDPCompLayerFlags(ctx, list);
1607 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001608 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001609 reset(ctx);
1610 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1611 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001612 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001613 }
1614 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001615 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1616 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001617 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001618 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001619
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001620 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001621 ALOGD("GEOMETRY change: %d",
1622 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001623 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001624 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001625 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626 }
1627
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001628 mCachedFrame.cacheAll(list);
1629 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001630 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001631}
1632
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001633bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301634
1635 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301636 int mdpIndex = mCurrentFrame.layerToMDP[index];
1637 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1638 info.pipeInfo = new MdpYUVPipeInfo;
1639 info.rot = NULL;
1640 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301641
1642 pipe_info.lIndex = ovutils::OV_INVALID;
1643 pipe_info.rIndex = ovutils::OV_INVALID;
1644
Saurabh Shahc62f3982014-03-05 14:28:26 -08001645 Overlay::PipeSpecs pipeSpecs;
1646 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1647 pipeSpecs.needsScaling = true;
1648 pipeSpecs.dpy = mDpy;
1649 pipeSpecs.fb = false;
1650
1651 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301652 if(pipe_info.lIndex == ovutils::OV_INVALID){
1653 bRet = false;
1654 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1655 __FUNCTION__);
1656 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001657 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301658 if(pipe_info.rIndex == ovutils::OV_INVALID){
1659 bRet = false;
1660 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1661 __FUNCTION__);
1662 }
1663 return bRet;
1664}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001665
1666int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1667 int fd = -1;
1668 if (mOverlapIndex != -1) {
1669 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
1670 if (fd < 0) {
1671 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
1672 mOverlapIndex = -1;
1673 }
1674 }
1675 return fd;
1676}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001677//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001678
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001679void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301680 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001681 //If 4k2k Yuv layer split is possible, and if
1682 //fbz is above 4k2k layer, increment fb zorder by 1
1683 //as we split 4k2k layer and increment zorder for right half
1684 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001685 if(!ctx)
1686 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001687 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301688 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1689 index++) {
1690 if(!mCurrentFrame.isFBComposed[index]) {
1691 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1692 mdpNextZOrder++;
1693 }
1694 mdpNextZOrder++;
1695 hwc_layer_1_t* layer = &list->hwLayers[index];
1696 private_handle_t *hnd = (private_handle_t *)layer->handle;
1697 if(is4kx2kYuvBuffer(hnd)) {
1698 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1699 mCurrentFrame.fbZ += 1;
1700 mdpNextZOrder++;
1701 //As we split 4kx2k yuv layer and program to 2 VG pipes
1702 //(if available) increase mdpcount by 1.
1703 mCurrentFrame.mdpCount++;
1704 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001705 }
1706 }
1707 }
radhakrishnac9a67412013-09-25 17:40:42 +05301708}
1709
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001710/*
1711 * Configures pipe(s) for MDP composition
1712 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001713int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001714 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001715 MdpPipeInfoNonSplit& mdp_info =
1716 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001717 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1718 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1719 eIsFg isFg = IS_FG_OFF;
1720 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001721
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001722 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1723 __FUNCTION__, layer, zOrder, dest);
1724
Saurabh Shah88e4d272013-09-03 13:31:29 -07001725 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001726 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001727}
1728
Saurabh Shah88e4d272013-09-03 13:31:29 -07001729bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001730 hwc_display_contents_1_t* list) {
1731 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001732
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001733 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001734
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001735 hwc_layer_1_t* layer = &list->hwLayers[index];
1736 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301737 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001738 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301739 continue;
1740 }
1741 }
1742
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001743 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001744 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001745 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001746 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001747 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001748
Saurabh Shahc62f3982014-03-05 14:28:26 -08001749 Overlay::PipeSpecs pipeSpecs;
1750 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1751 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1752 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1753 (qdutils::MDPVersion::getInstance().is8x26() and
1754 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1755 pipeSpecs.dpy = mDpy;
1756 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001757 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001758
Saurabh Shahc62f3982014-03-05 14:28:26 -08001759 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1760
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001761 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001762 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001763 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001764 }
1765 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001766 return true;
1767}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001768
radhakrishnac9a67412013-09-25 17:40:42 +05301769int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1770 PipeLayerPair& PipeLayerPair) {
1771 MdpYUVPipeInfo& mdp_info =
1772 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1773 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1774 eIsFg isFg = IS_FG_OFF;
1775 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1776 eDest lDest = mdp_info.lIndex;
1777 eDest rDest = mdp_info.rIndex;
1778
1779 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1780 lDest, rDest, &PipeLayerPair.rot);
1781}
1782
Saurabh Shah88e4d272013-09-03 13:31:29 -07001783bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001784
Raj Kamal4393eaa2014-06-06 13:45:20 +05301785 if(!isEnabled() or !mModeOn) {
1786 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301787 return true;
1788 }
1789
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001790 // Set the Handle timeout to true for MDP or MIXED composition.
1791 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1792 sHandleTimeout = true;
1793 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001794
1795 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001796 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001797
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001798 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1799 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001800 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001801 if(mCurrentFrame.isFBComposed[i]) continue;
1802
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001803 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001804 private_handle_t *hnd = (private_handle_t *)layer->handle;
1805 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001806 if (!(layer->flags & HWC_COLOR_FILL)) {
1807 ALOGE("%s handle null", __FUNCTION__);
1808 return false;
1809 }
1810 // No PLAY for Color layer
1811 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1812 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001813 }
1814
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001815 int mdpIndex = mCurrentFrame.layerToMDP[i];
1816
radhakrishnac9a67412013-09-25 17:40:42 +05301817 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1818 {
1819 MdpYUVPipeInfo& pipe_info =
1820 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1821 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1822 ovutils::eDest indexL = pipe_info.lIndex;
1823 ovutils::eDest indexR = pipe_info.rIndex;
1824 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301825 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301826 if(rot) {
1827 rot->queueBuffer(fd, offset);
1828 fd = rot->getDstMemId();
1829 offset = rot->getDstOffset();
1830 }
1831 if(indexL != ovutils::OV_INVALID) {
1832 ovutils::eDest destL = (ovutils::eDest)indexL;
1833 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1834 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1835 if (!ov.queueBuffer(fd, offset, destL)) {
1836 ALOGE("%s: queueBuffer failed for display:%d",
1837 __FUNCTION__, mDpy);
1838 return false;
1839 }
1840 }
1841
1842 if(indexR != ovutils::OV_INVALID) {
1843 ovutils::eDest destR = (ovutils::eDest)indexR;
1844 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1845 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1846 if (!ov.queueBuffer(fd, offset, destR)) {
1847 ALOGE("%s: queueBuffer failed for display:%d",
1848 __FUNCTION__, mDpy);
1849 return false;
1850 }
1851 }
1852 }
1853 else{
1854 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001855 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301856 ovutils::eDest dest = pipe_info.index;
1857 if(dest == ovutils::OV_INVALID) {
1858 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001859 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301860 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001861
radhakrishnac9a67412013-09-25 17:40:42 +05301862 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1863 continue;
1864 }
1865
Sushil Chauhandefd3522014-05-13 18:17:12 -07001866 if (!mDpy && (i == mOverlapIndex)) {
1867 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1868 }
1869
radhakrishnac9a67412013-09-25 17:40:42 +05301870 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1871 using pipe: %d", __FUNCTION__, layer,
1872 hnd, dest );
1873
1874 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301875 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301876
1877 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1878 if(rot) {
1879 if(!rot->queueBuffer(fd, offset))
1880 return false;
1881 fd = rot->getDstMemId();
1882 offset = rot->getDstOffset();
1883 }
1884
1885 if (!ov.queueBuffer(fd, offset, dest)) {
1886 ALOGE("%s: queueBuffer failed for display:%d ",
1887 __FUNCTION__, mDpy);
1888 return false;
1889 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001890 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001891
1892 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001893 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001894 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001895}
1896
Saurabh Shah88e4d272013-09-03 13:31:29 -07001897//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001898
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001899void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301900 hwc_display_contents_1_t* list){
1901 //if 4kx2k yuv layer is totally present in either in left half
1902 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301903 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301904 if(mCurrentFrame.fbZ >= 0) {
1905 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1906 index++) {
1907 if(!mCurrentFrame.isFBComposed[index]) {
1908 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1909 mdpNextZOrder++;
1910 }
1911 mdpNextZOrder++;
1912 hwc_layer_1_t* layer = &list->hwLayers[index];
1913 private_handle_t *hnd = (private_handle_t *)layer->handle;
1914 if(is4kx2kYuvBuffer(hnd)) {
1915 hwc_rect_t dst = layer->displayFrame;
1916 if((dst.left > lSplit) || (dst.right < lSplit)) {
1917 mCurrentFrame.mdpCount += 1;
1918 }
1919 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1920 mCurrentFrame.fbZ += 1;
1921 mdpNextZOrder++;
1922 }
1923 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001924 }
radhakrishnac9a67412013-09-25 17:40:42 +05301925 }
1926}
1927
Saurabh Shah88e4d272013-09-03 13:31:29 -07001928bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001929 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001930
Saurabh Shahc62f3982014-03-05 14:28:26 -08001931 const int lSplit = getLeftSplit(ctx, mDpy);
1932 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001933 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001934 pipe_info.lIndex = ovutils::OV_INVALID;
1935 pipe_info.rIndex = ovutils::OV_INVALID;
1936
Saurabh Shahc62f3982014-03-05 14:28:26 -08001937 Overlay::PipeSpecs pipeSpecs;
1938 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1939 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1940 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
1941 pipeSpecs.dpy = mDpy;
1942 pipeSpecs.mixer = Overlay::MIXER_LEFT;
1943 pipeSpecs.fb = false;
1944
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001945 // Acquire pipe only for the updating half
1946 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
1947 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
1948
1949 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001950 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001951 if(pipe_info.lIndex == ovutils::OV_INVALID)
1952 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001953 }
1954
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001955 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001956 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
1957 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001958 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001959 return false;
1960 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001961
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001962 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001963}
1964
Saurabh Shah88e4d272013-09-03 13:31:29 -07001965bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001966 hwc_display_contents_1_t* list) {
1967 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001968
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001969 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001970
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001971 hwc_layer_1_t* layer = &list->hwLayers[index];
1972 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301973 hwc_rect_t dst = layer->displayFrame;
1974 const int lSplit = getLeftSplit(ctx, mDpy);
1975 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1976 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001977 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301978 continue;
1979 }
1980 }
1981 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001982 int mdpIndex = mCurrentFrame.layerToMDP[index];
1983 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001984 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001985 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001986 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001987
Saurabh Shahc62f3982014-03-05 14:28:26 -08001988 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
1989 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
1990 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001991 return false;
1992 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001993 }
1994 return true;
1995}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001996
radhakrishnac9a67412013-09-25 17:40:42 +05301997int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1998 PipeLayerPair& PipeLayerPair) {
1999 const int lSplit = getLeftSplit(ctx, mDpy);
2000 hwc_rect_t dst = layer->displayFrame;
2001 if((dst.left > lSplit)||(dst.right < lSplit)){
2002 MdpYUVPipeInfo& mdp_info =
2003 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2004 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2005 eIsFg isFg = IS_FG_OFF;
2006 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2007 eDest lDest = mdp_info.lIndex;
2008 eDest rDest = mdp_info.rIndex;
2009
2010 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2011 lDest, rDest, &PipeLayerPair.rot);
2012 }
2013 else{
2014 return configure(ctx, layer, PipeLayerPair);
2015 }
2016}
2017
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002018/*
2019 * Configures pipe(s) for MDP composition
2020 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002021int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002022 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002023 MdpPipeInfoSplit& mdp_info =
2024 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002025 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2026 eIsFg isFg = IS_FG_OFF;
2027 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2028 eDest lDest = mdp_info.lIndex;
2029 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002030
2031 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2032 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2033
Saurabh Shah88e4d272013-09-03 13:31:29 -07002034 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002035 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002036}
2037
Saurabh Shah88e4d272013-09-03 13:31:29 -07002038bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002039
Raj Kamal4393eaa2014-06-06 13:45:20 +05302040 if(!isEnabled() or !mModeOn) {
2041 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302042 return true;
2043 }
2044
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002045 // Set the Handle timeout to true for MDP or MIXED composition.
2046 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2047 sHandleTimeout = true;
2048 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002049
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002050 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002051 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002052
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002053 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2054 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002055 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002056 if(mCurrentFrame.isFBComposed[i]) continue;
2057
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002058 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002059 private_handle_t *hnd = (private_handle_t *)layer->handle;
2060 if(!hnd) {
2061 ALOGE("%s handle null", __FUNCTION__);
2062 return false;
2063 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002064
2065 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2066 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002067 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002068
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002069 int mdpIndex = mCurrentFrame.layerToMDP[i];
2070
radhakrishnac9a67412013-09-25 17:40:42 +05302071 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2072 {
2073 MdpYUVPipeInfo& pipe_info =
2074 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2075 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2076 ovutils::eDest indexL = pipe_info.lIndex;
2077 ovutils::eDest indexR = pipe_info.rIndex;
2078 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302079 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302080 if(rot) {
2081 rot->queueBuffer(fd, offset);
2082 fd = rot->getDstMemId();
2083 offset = rot->getDstOffset();
2084 }
2085 if(indexL != ovutils::OV_INVALID) {
2086 ovutils::eDest destL = (ovutils::eDest)indexL;
2087 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2088 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2089 if (!ov.queueBuffer(fd, offset, destL)) {
2090 ALOGE("%s: queueBuffer failed for display:%d",
2091 __FUNCTION__, mDpy);
2092 return false;
2093 }
2094 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002095
radhakrishnac9a67412013-09-25 17:40:42 +05302096 if(indexR != ovutils::OV_INVALID) {
2097 ovutils::eDest destR = (ovutils::eDest)indexR;
2098 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2099 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2100 if (!ov.queueBuffer(fd, offset, destR)) {
2101 ALOGE("%s: queueBuffer failed for display:%d",
2102 __FUNCTION__, mDpy);
2103 return false;
2104 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002105 }
2106 }
radhakrishnac9a67412013-09-25 17:40:42 +05302107 else{
2108 MdpPipeInfoSplit& pipe_info =
2109 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2110 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002111
radhakrishnac9a67412013-09-25 17:40:42 +05302112 ovutils::eDest indexL = pipe_info.lIndex;
2113 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002114
Sushil Chauhandefd3522014-05-13 18:17:12 -07002115 if (!mDpy && (i == mOverlapIndex)) {
2116 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2117 }
2118
radhakrishnac9a67412013-09-25 17:40:42 +05302119 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302120 int offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302121
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002122 if(ctx->mAD->draw(ctx, fd, offset)) {
2123 fd = ctx->mAD->getDstFd();
2124 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002125 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002126
radhakrishnac9a67412013-09-25 17:40:42 +05302127 if(rot) {
2128 rot->queueBuffer(fd, offset);
2129 fd = rot->getDstMemId();
2130 offset = rot->getDstOffset();
2131 }
2132
2133 //************* play left mixer **********
2134 if(indexL != ovutils::OV_INVALID) {
2135 ovutils::eDest destL = (ovutils::eDest)indexL;
2136 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2137 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2138 if (!ov.queueBuffer(fd, offset, destL)) {
2139 ALOGE("%s: queueBuffer failed for left mixer",
2140 __FUNCTION__);
2141 return false;
2142 }
2143 }
2144
2145 //************* play right mixer **********
2146 if(indexR != ovutils::OV_INVALID) {
2147 ovutils::eDest destR = (ovutils::eDest)indexR;
2148 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2149 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2150 if (!ov.queueBuffer(fd, offset, destR)) {
2151 ALOGE("%s: queueBuffer failed for right mixer",
2152 __FUNCTION__);
2153 return false;
2154 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002155 }
2156 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002157
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002158 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2159 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002160
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002161 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002162}
Saurabh Shahab47c692014-02-12 18:45:57 -08002163
2164//================MDPCompSrcSplit==============================================
2165bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002166 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002167 private_handle_t *hnd = (private_handle_t *)layer->handle;
2168 hwc_rect_t dst = layer->displayFrame;
2169 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2170 pipe_info.lIndex = ovutils::OV_INVALID;
2171 pipe_info.rIndex = ovutils::OV_INVALID;
2172
2173 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2174 //should have a higher priority than the right one. Pipe priorities are
2175 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002176
Saurabh Shahc62f3982014-03-05 14:28:26 -08002177 Overlay::PipeSpecs pipeSpecs;
2178 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2179 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2180 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2181 pipeSpecs.dpy = mDpy;
2182 pipeSpecs.fb = false;
2183
Saurabh Shahab47c692014-02-12 18:45:57 -08002184 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002185 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002186 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002187 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002188 }
2189
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002190 /* Use 2 pipes IF
2191 a) Layer's crop width is > 2048 or
2192 b) Layer's dest width > 2048 or
2193 c) On primary, driver has indicated with caps to split always. This is
2194 based on an empirically derived value of panel height. Applied only
2195 if the layer's width is > mixer's width
2196 */
2197
2198 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2199 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2200 int lSplit = getLeftSplit(ctx, mDpy);
2201 int dstWidth = dst.right - dst.left;
2202 int cropWidth = crop.right - crop.left;
2203
2204 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2205 cropWidth > qdutils::MAX_DISPLAY_DIM or
2206 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002207 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002208 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002209 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002210 }
2211
2212 // Return values
2213 // 1 Left pipe is higher priority, do nothing.
2214 // 0 Pipes of same priority.
2215 //-1 Right pipe is of higher priority, needs swap.
2216 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2217 pipe_info.rIndex) == -1) {
2218 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002219 }
2220 }
2221
2222 return true;
2223}
2224
Saurabh Shahab47c692014-02-12 18:45:57 -08002225int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2226 PipeLayerPair& PipeLayerPair) {
2227 private_handle_t *hnd = (private_handle_t *)layer->handle;
2228 if(!hnd) {
2229 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2230 return -1;
2231 }
2232 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2233 MdpPipeInfoSplit& mdp_info =
2234 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2235 Rotator **rot = &PipeLayerPair.rot;
2236 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2237 eIsFg isFg = IS_FG_OFF;
2238 eDest lDest = mdp_info.lIndex;
2239 eDest rDest = mdp_info.rIndex;
2240 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2241 hwc_rect_t dst = layer->displayFrame;
2242 int transform = layer->transform;
2243 eTransform orient = static_cast<eTransform>(transform);
2244 const int downscale = 0;
2245 int rotFlags = ROT_FLAGS_NONE;
2246 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2247 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2248
2249 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2250 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2251
2252 // Handle R/B swap
2253 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2254 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2255 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2256 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2257 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2258 }
2259
Saurabh Shah97e2d802014-04-14 18:03:54 -07002260 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
2261 setMdpFlags(layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002262
2263 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2264 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002265 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002266 }
2267
2268 if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
2269 (*rot) = ctx->mRotMgr->getNext();
2270 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002271 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002272 //If the video is using a single pipe, enable BWC
2273 if(rDest == OV_INVALID) {
2274 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2275 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002276 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002277 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002278 ALOGE("%s: configRotator failed!", __FUNCTION__);
2279 return -1;
2280 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002281 whf.format = (*rot)->getDstFormat();
2282 updateSource(orient, whf, crop);
2283 rotFlags |= ROT_PREROTATED;
2284 }
2285
2286 //If 2 pipes being used, divide layer into half, crop and dst
2287 hwc_rect_t cropL = crop;
2288 hwc_rect_t cropR = crop;
2289 hwc_rect_t dstL = dst;
2290 hwc_rect_t dstR = dst;
2291 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2292 cropL.right = (crop.right + crop.left) / 2;
2293 cropR.left = cropL.right;
2294 sanitizeSourceCrop(cropL, cropR, hnd);
2295
2296 //Swap crops on H flip since 2 pipes are being used
2297 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2298 hwc_rect_t tmp = cropL;
2299 cropL = cropR;
2300 cropR = tmp;
2301 }
2302
2303 dstL.right = (dst.right + dst.left) / 2;
2304 dstR.left = dstL.right;
2305 }
2306
2307 //For the mdp, since either we are pre-rotating or MDP does flips
2308 orient = OVERLAY_TRANSFORM_0;
2309 transform = 0;
2310
2311 //configure left pipe
2312 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002313 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002314 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2315 (ovutils::eBlending) getBlending(layer->blending));
2316
2317 if(configMdp(ctx->mOverlay, pargL, orient,
2318 cropL, dstL, metadata, lDest) < 0) {
2319 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2320 return -1;
2321 }
2322 }
2323
2324 //configure right pipe
2325 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002326 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002327 static_cast<eRotFlags>(rotFlags),
2328 layer->planeAlpha,
2329 (ovutils::eBlending) getBlending(layer->blending));
2330 if(configMdp(ctx->mOverlay, pargR, orient,
2331 cropR, dstR, metadata, rDest) < 0) {
2332 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2333 return -1;
2334 }
2335 }
2336
2337 return 0;
2338}
2339
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002340}; //namespace
2341