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