blob: 6f99a502a8faf6cc9d183ee18383a99210963b09 [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
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
138 // Idle invalidation is not necessary on command mode panels
139 long idle_timeout = DEFAULT_IDLE_TIME;
140 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
141 if(atoi(property) != 0)
142 idle_timeout = atoi(property);
143 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800144
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400145 //create Idle Invalidator only when not disabled through property
146 if(idle_timeout != -1)
147 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800148
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400149 if(idleInvalidator == NULL) {
150 ALOGE("%s: failed to instantiate idleInvalidator object",
151 __FUNCTION__);
152 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530153 idleInvalidator->init(timeout_handler, ctx,
154 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400155 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800156 }
radhakrishnac9a67412013-09-25 17:40:42 +0530157
Saurabh Shah7c727642014-06-02 15:47:14 -0700158 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
159 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
160 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
161 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
radhakrishnac9a67412013-09-25 17:40:42 +0530162 sEnable4k2kYUVSplit = true;
163 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164
165 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
166 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
167 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
169 HWC_DISPLAY_PRIMARY);
170 }
171
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700172 return true;
173}
174
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800175void MDPComp::reset(hwc_context_t *ctx) {
176 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700177 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800178 ctx->mOverlay->clear(mDpy);
179 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700180}
181
Raj Kamal4393eaa2014-06-06 13:45:20 +0530182void MDPComp::reset() {
183 sHandleTimeout = false;
184 mModeOn = false;
185}
186
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700187void MDPComp::timeout_handler(void *udata) {
188 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
189
190 if(!ctx) {
191 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
192 return;
193 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800194 Locker::Autolock _l(ctx->mDrawLock);
195 // Handle timeout event only if the previous composition is MDP or MIXED.
196 if(!sHandleTimeout) {
197 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
198 return;
199 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700200 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700201 ALOGE("%s: HWC proc not registered", __FUNCTION__);
202 return;
203 }
204 sIdleFallBack = true;
205 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700206 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700207}
208
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800209void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800210 hwc_display_contents_1_t* list) {
211 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800212
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800213 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 if(!mCurrentFrame.isFBComposed[index]) {
216 layerProp[index].mFlags |= HWC_MDPCOMP;
217 layer->compositionType = HWC_OVERLAY;
218 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700220 /* Drop the layer when its already present in FB OR when it lies
221 * outside frame's ROI */
222 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700224 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800225 }
226 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500228
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800229void MDPComp::setRedraw(hwc_context_t *ctx,
230 hwc_display_contents_1_t* list) {
231 mCurrentFrame.needsRedraw = false;
232 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
233 (list->flags & HWC_GEOMETRY_CHANGED) ||
234 isSkipPresent(ctx, mDpy)) {
235 mCurrentFrame.needsRedraw = true;
236 }
237}
238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700240 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800242
Saurabh Shahaa236822013-04-24 18:07:26 -0700243void MDPComp::FrameInfo::reset(const int& numLayers) {
244 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245 if(mdpToLayer[i].pipeInfo) {
246 delete mdpToLayer[i].pipeInfo;
247 mdpToLayer[i].pipeInfo = NULL;
248 //We dont own the rotator
249 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800250 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800251 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800252
253 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
254 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700255 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800256
Saurabh Shahaa236822013-04-24 18:07:26 -0700257 layerCount = numLayers;
258 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800259 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700260 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800261 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800262}
263
Saurabh Shahaa236822013-04-24 18:07:26 -0700264void MDPComp::FrameInfo::map() {
265 // populate layer and MDP maps
266 int mdpIdx = 0;
267 for(int idx = 0; idx < layerCount; idx++) {
268 if(!isFBComposed[idx]) {
269 mdpToLayer[mdpIdx].listIndex = idx;
270 layerToMDP[idx] = mdpIdx++;
271 }
272 }
273}
274
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800275MDPComp::LayerCache::LayerCache() {
276 reset();
277}
278
279void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700280 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530281 memset(&isFBComposed, true, sizeof(isFBComposed));
282 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700284}
285
286void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530287 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700288 for(int i = 0; i < numAppLayers; i++) {
289 hnd[i] = list->hwLayers[i].handle;
290 }
291}
292
293void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700294 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530295 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
296 memcpy(&drop, &curFrame.drop, sizeof(drop));
297}
298
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800299bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
300 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530301 if(layerCount != curFrame.layerCount)
302 return false;
303 for(int i = 0; i < curFrame.layerCount; i++) {
304 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
305 (curFrame.drop[i] != drop[i])) {
306 return false;
307 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800308 if(curFrame.isFBComposed[i] &&
309 (hnd[i] != list->hwLayers[i].handle)){
310 return false;
311 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530312 }
313 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800314}
315
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700316bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
317 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800318 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700319 (not isValidDimension(ctx,layer))
320 //More conditions here, SKIP, sRGB+Blend etc
321 ) {
322 return false;
323 }
324 return true;
325}
326
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530327bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800328 private_handle_t *hnd = (private_handle_t *)layer->handle;
329
330 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700331 if (layer->flags & HWC_COLOR_FILL) {
332 // Color layer
333 return true;
334 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800335 ALOGE("%s: layer handle is NULL", __FUNCTION__);
336 return false;
337 }
338
Naseer Ahmede850a802013-09-06 13:12:52 -0400339 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400340 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400341 return false;
342
Saurabh Shah62e1d732013-09-17 10:44:05 -0700343 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700344 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700345 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700346 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
347 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700348 int dst_w = dst.right - dst.left;
349 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800350 float w_scale = ((float)crop_w / (float)dst_w);
351 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530352 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700353
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800354 /* Workaround for MDP HW limitation in DSI command mode panels where
355 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
356 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530357 * There also is a HW limilation in MDP, minimum block size is 2x2
358 * Fallback to GPU if height is less than 2.
359 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800360 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800361 return false;
362
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800363 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530364 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800365 const float w_dscale = w_scale;
366 const float h_dscale = h_scale;
367
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800368 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700369
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530370 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700371 /* On targets that doesnt support Decimation (eg.,8x26)
372 * maximum downscale support is overlay pipe downscale.
373 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530374 if(crop_w > mdpHw.getMaxMixerWidth() ||
375 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700376 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800377 return false;
378 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700379 // Decimation on macrotile format layers is not supported.
380 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530381 /* Bail out if
382 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700383 * 2. exceeds maximum downscale limit
384 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530385 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
386 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700387 w_dscale > maxMDPDownscale ||
388 h_dscale > maxMDPDownscale) {
389 return false;
390 }
391 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800392 return false;
393 }
394 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700395 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700396 return false;
397 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700398 }
399
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800400 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530401 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800402 const float w_uscale = 1.0f / w_scale;
403 const float h_uscale = 1.0f / h_scale;
404
405 if(w_uscale > upscale || h_uscale > upscale)
406 return false;
407 }
408
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800409 return true;
410}
411
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800412bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700413 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800414
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800415 if(!isEnabled()) {
416 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700417 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530418 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530419 qdutils::MDPVersion::getInstance().is8x16() ||
420 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800421 ctx->mVideoTransFlag &&
422 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700423 //1 Padding round to shift pipes across mixers
424 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
425 __FUNCTION__);
426 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800427 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800428 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800429 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700430 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700431 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530432 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
433 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700434 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700435 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800437}
438
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800439void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
440 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
441 fbRect = getIntersection(fbRect, roi);
442}
443
444/* 1) Identify layers that are not visible or lying outside the updating ROI and
445 * drop them from composition.
446 * 2) If we have a scaling layer which needs cropping against generated
447 * ROI, reset ROI to full resolution. */
448bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
449 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700450 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800451 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800452
453 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800454 if(!isValidRect(visibleRect)) {
455 mCurrentFrame.drop[i] = true;
456 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800457 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800458 }
459
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700460 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700461 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800462 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700463
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464 if(!isValidRect(res)) {
465 mCurrentFrame.drop[i] = true;
466 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800467 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468 /* Reset frame ROI when any layer which needs scaling also needs ROI
469 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800470 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800471 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
473 mCurrentFrame.dropCount = 0;
474 return false;
475 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800476
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800477 /* deduct any opaque region from visibleRect */
478 if (layer->blending == HWC_BLENDING_NONE)
479 visibleRect = deductRect(visibleRect, res);
480 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700481 }
482 return true;
483}
484
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800485/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
486 * are updating. If DirtyRegion is applicable, calculate it by accounting all
487 * the changing layer's dirtyRegion. */
488void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
489 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700490 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800491 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700492 return;
493
494 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800495 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
496 (int)ctx->dpyAttr[mDpy].yres};
497
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800499 hwc_layer_1_t* layer = &list->hwLayers[index];
500 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800501 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700502 hwc_rect_t dst = layer->displayFrame;
503 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800504
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800505#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800506 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700507 {
508 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
509 int x_off = dst.left - src.left;
510 int y_off = dst.top - src.top;
511 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
512 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800513#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800514
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800515 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700516 }
517 }
518
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519 /* No layer is updating. Still SF wants a refresh.*/
520 if(!isValidRect(roi))
521 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800522
523 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800524 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800525
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800526 ctx->listStats[mDpy].lRoi = roi;
527 if(!validateAndApplyROI(ctx, list))
528 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529
530 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800531 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
532 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
533}
534
535void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
536 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
537 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
538
539 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
540 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
541 fbRect = getUnion(l_fbRect, r_fbRect);
542}
543/* 1) Identify layers that are not visible or lying outside BOTH the updating
544 * ROI's and drop them from composition. If a layer is spanning across both
545 * the halves of the screen but needed by only ROI, the non-contributing
546 * half will not be programmed for MDP.
547 * 2) If we have a scaling layer which needs cropping against generated
548 * ROI, reset ROI to full resolution. */
549bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
550 hwc_display_contents_1_t* list) {
551
552 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
553
554 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
555 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
556
557 for(int i = numAppLayers - 1; i >= 0; i--){
558 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
559 {
560 mCurrentFrame.drop[i] = true;
561 mCurrentFrame.dropCount++;
562 continue;
563 }
564
565 const hwc_layer_1_t* layer = &list->hwLayers[i];
566 hwc_rect_t dstRect = layer->displayFrame;
567
568 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
569 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
570 hwc_rect_t res = getUnion(l_res, r_res);
571
572 if(!isValidRect(l_res) && !isValidRect(r_res)) {
573 mCurrentFrame.drop[i] = true;
574 mCurrentFrame.dropCount++;
575 } else {
576 /* Reset frame ROI when any layer which needs scaling also needs ROI
577 * cropping */
578 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
579 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
580 mCurrentFrame.dropCount = 0;
581 return false;
582 }
583
584 if (layer->blending == HWC_BLENDING_NONE) {
585 visibleRectL = deductRect(visibleRectL, l_res);
586 visibleRectR = deductRect(visibleRectR, r_res);
587 }
588 }
589 }
590 return true;
591}
592/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
593 * are updating. If DirtyRegion is applicable, calculate it by accounting all
594 * the changing layer's dirtyRegion. */
595void MDPCompSplit::generateROI(hwc_context_t *ctx,
596 hwc_display_contents_1_t* list) {
597 if(!canPartialUpdate(ctx, list))
598 return;
599
600 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
601 int lSplit = getLeftSplit(ctx, mDpy);
602
603 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
604 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
605
606 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
607 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
608
609 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
610 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
611
612 for(int index = 0; index < numAppLayers; index++ ) {
613 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800614 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800615 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800616 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700617 hwc_rect_t dst = layer->displayFrame;
618 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800619
620#ifdef QCOM_BSP
621 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700622 {
623 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
624 int x_off = dst.left - src.left;
625 int y_off = dst.top - src.top;
626 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
627 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800628#endif
629
630 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
631 if(isValidRect(l_dst))
632 l_roi = getUnion(l_roi, l_dst);
633
634 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
635 if(isValidRect(r_dst))
636 r_roi = getUnion(r_roi, r_dst);
637 }
638 }
639
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700640 /* For panels that cannot accept commands in both the interfaces, we cannot
641 * send two ROI's (for each half). We merge them into single ROI and split
642 * them across lSplit for MDP mixer use. The ROI's will be merged again
643 * finally before udpating the panel in the driver. */
644 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
645 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
646 l_roi = getIntersection(temp_roi, l_frame);
647 r_roi = getIntersection(temp_roi, r_frame);
648 }
649
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800650 /* No layer is updating. Still SF wants a refresh. */
651 if(!isValidRect(l_roi) && !isValidRect(r_roi))
652 return;
653
654 l_roi = getSanitizeROI(l_roi, l_frame);
655 r_roi = getSanitizeROI(r_roi, r_frame);
656
657 ctx->listStats[mDpy].lRoi = l_roi;
658 ctx->listStats[mDpy].rRoi = r_roi;
659
660 if(!validateAndApplyROI(ctx, list))
661 resetROI(ctx, mDpy);
662
663 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
664 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
665 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
666 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
667 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
668 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700669}
670
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800671/* Checks for conditions where all the layers marked for MDP comp cannot be
672 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800673bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800674 hwc_display_contents_1_t* list){
675
Saurabh Shahaa236822013-04-24 18:07:26 -0700676 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800677 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800678
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700679 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700680 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
681 return false;
682 }
683
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800684 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700685 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
686 __FUNCTION__,
687 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800688 return false;
689 }
690
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530691 MDPVersion& mdpHw = MDPVersion::getInstance();
692 if(mDpy > HWC_DISPLAY_PRIMARY &&
693 (priDispW > mdpHw.getMaxMixerWidth()) &&
694 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800695 // Disable MDP comp on Secondary when the primary is highres panel and
696 // the secondary is a normal 1080p, because, MDP comp on secondary under
697 // in such usecase, decimation gets used for downscale and there will be
698 // a quality mismatch when there will be a fallback to GPU comp
699 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
700 __FUNCTION__);
701 return false;
702 }
703
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800704 // check for action safe flag and downscale mode which requires scaling.
705 if(ctx->dpyAttr[mDpy].mActionSafePresent
706 || ctx->dpyAttr[mDpy].mDownScaleMode) {
707 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
708 return false;
709 }
710
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800711 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800712 hwc_layer_1_t* layer = &list->hwLayers[i];
713 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800714
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800715 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700716 if(!canUseRotator(ctx, mDpy)) {
717 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
718 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700719 return false;
720 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800721 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530722
723 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
724 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700725 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530726 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
727 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
728 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800729 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700730
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700731 if(ctx->mAD->isDoable()) {
732 return false;
733 }
734
Saurabh Shahaa236822013-04-24 18:07:26 -0700735 //If all above hard conditions are met we can do full or partial MDP comp.
736 bool ret = false;
737 if(fullMDPComp(ctx, list)) {
738 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700739 } else if(fullMDPCompWithPTOR(ctx, list)) {
740 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700741 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700742 ret = true;
743 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530744
Saurabh Shahaa236822013-04-24 18:07:26 -0700745 return ret;
746}
747
748bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700749
750 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
751 return false;
752
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700753 //Will benefit presentation / secondary-only layer.
754 if((mDpy > HWC_DISPLAY_PRIMARY) &&
755 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
756 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
757 return false;
758 }
759
760 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
761 for(int i = 0; i < numAppLayers; i++) {
762 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700763 if(not mCurrentFrame.drop[i] and
764 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700765 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
766 return false;
767 }
768 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800769
Saurabh Shahaa236822013-04-24 18:07:26 -0700770 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700771 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
772 sizeof(mCurrentFrame.isFBComposed));
773 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
774 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700775
radhakrishnac9a67412013-09-25 17:40:42 +0530776 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800777 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530778 }
779
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800780 if(!postHeuristicsHandling(ctx, list)) {
781 ALOGD_IF(isDebug(), "post heuristic handling failed");
782 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700783 return false;
784 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700785 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
786 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700787 return true;
788}
789
Sushil Chauhandefd3522014-05-13 18:17:12 -0700790/* Full MDP Composition with Peripheral Tiny Overlap Removal.
791 * MDP bandwidth limitations can be avoided, if the overlap region
792 * covered by the smallest layer at a higher z-order, gets composed
793 * by Copybit on a render buffer, which can be queued to MDP.
794 */
795bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
796 hwc_display_contents_1_t* list) {
797
798 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
799 const int stagesForMDP = min(sMaxPipesPerMixer,
800 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
801
802 // Hard checks where we cannot use this mode
803 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
804 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
805 return false;
806 }
807
808 // Frame level checks
809 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
810 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
811 isSecurePresent(ctx, mDpy)) {
812 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
813 return false;
814 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700815 // MDP comp checks
816 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700817 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700818 if(not isSupportedForMDPComp(ctx, layer)) {
819 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
820 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700821 }
822 }
823
Sushil Chauhandefd3522014-05-13 18:17:12 -0700824 /* We cannot use this composition mode, if:
825 1. A below layer needs scaling.
826 2. Overlap is not peripheral to display.
827 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700828 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700829 */
830
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700831 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
832 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
833 memset(overlapRect, 0, sizeof(overlapRect));
834 int layerPixelCount, minPixelCount = 0;
835 int numPTORLayersFound = 0;
836 for (int i = numAppLayers-1; (i >= 0 &&
837 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700838 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700839 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700841 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
842 // PTOR layer should be peripheral and cannot have transform
843 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
844 has90Transform(layer)) {
845 continue;
846 }
847 if((3 * (layerPixelCount + minPixelCount)) >
848 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
849 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
850 continue;
851 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700852 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700853 for (int j = i-1; j >= 0; j--) {
854 // Check if the layers below this layer qualifies for PTOR comp
855 hwc_layer_1_t* layer = &list->hwLayers[j];
856 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700857 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700858 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700859 if (isValidRect(getIntersection(dispFrame, disFrame))) {
860 if (has90Transform(layer) || needsScaling(layer)) {
861 found = false;
862 break;
863 }
864 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700865 }
866 }
867 // Store the minLayer Index
868 if(found) {
869 minLayerIndex[numPTORLayersFound] = i;
870 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
871 minPixelCount += layerPixelCount;
872 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700873 }
874 }
875
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700876 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
877 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
878 __FUNCTION__);
879 // reset second minLayerIndex[1];
880 minLayerIndex[1] = -1;
881 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700882 }
883
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700884 // No overlap layers
885 if (!numPTORLayersFound)
886 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700887
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 ctx->mPtorInfo.count = numPTORLayersFound;
889 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
890 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
891 }
892
893 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
894 // reset PTOR
895 ctx->mPtorInfo.count = 0;
896 return false;
897 }
898 // Store the displayFrame and the sourceCrops of the layers
899 hwc_rect_t displayFrame[numAppLayers];
900 hwc_rect_t sourceCrop[numAppLayers];
901 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700902 hwc_layer_1_t* layer = &list->hwLayers[i];
903 displayFrame[i] = layer->displayFrame;
904 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700905 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700906
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700907 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
908 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
909
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 for(int j = 0; j < numPTORLayersFound; j++) {
911 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700912
913 // Update src crop of PTOR layer
914 hwc_layer_1_t* layer = &list->hwLayers[index];
915 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
916 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
917 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
918 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
919
920 // Store & update w, h, format of PTOR layer
921 private_handle_t *hnd = (private_handle_t *)layer->handle;
922 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
923 layerWhf[j] = whf;
924 hnd->width = renderBuf->width;
925 hnd->height = renderBuf->height;
926 hnd->format = renderBuf->format;
927
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700928 // Remove overlap from crop & displayFrame of below layers
929 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700930 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700931 if(!isValidRect(getIntersection(layer->displayFrame,
932 overlapRect[j]))) {
933 continue;
934 }
935 // Update layer attributes
936 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
937 hwc_rect_t destRect = deductRect(layer->displayFrame,
938 overlapRect[j]);
939 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
940 layer->transform);
941 layer->sourceCropf.left = (float)srcCrop.left;
942 layer->sourceCropf.top = (float)srcCrop.top;
943 layer->sourceCropf.right = (float)srcCrop.right;
944 layer->sourceCropf.bottom = (float)srcCrop.bottom;
945 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700946 }
947
948 mCurrentFrame.mdpCount = numAppLayers;
949 mCurrentFrame.fbCount = 0;
950 mCurrentFrame.fbZ = -1;
951
952 for (int j = 0; j < numAppLayers; j++)
953 mCurrentFrame.isFBComposed[j] = false;
954
955 bool result = postHeuristicsHandling(ctx, list);
956
957 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700958 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959 hwc_layer_1_t* layer = &list->hwLayers[i];
960 layer->displayFrame = displayFrame[i];
961 layer->sourceCropf.left = (float)sourceCrop[i].left;
962 layer->sourceCropf.top = (float)sourceCrop[i].top;
963 layer->sourceCropf.right = (float)sourceCrop[i].right;
964 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
965 }
966
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700967 // Restore w,h,f of PTOR layers
968 for (int i = 0; i < numPTORLayersFound; i++) {
969 int idx = ctx->mPtorInfo.layerIndex[i];
970 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
971 hnd->width = layerWhf[i].w;
972 hnd->height = layerWhf[i].h;
973 hnd->format = layerWhf[i].format;
974 }
975
Sushil Chauhandefd3522014-05-13 18:17:12 -0700976 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700977 // reset PTOR
978 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700979 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700980 } else {
981 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
982 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700983 }
984
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700985 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
986 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -0700987 return result;
988}
989
Saurabh Shahaa236822013-04-24 18:07:26 -0700990bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
991{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700992 if(!sEnableMixedMode) {
993 //Mixed mode is disabled. No need to even try caching.
994 return false;
995 }
996
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700997 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800998 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800999 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001000 cacheBasedComp(ctx, list);
1001 } else {
1002 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001003 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001004 }
1005
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001006 return ret;
1007}
1008
1009bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1010 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001011 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1012 return false;
1013
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001014 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001015 mCurrentFrame.reset(numAppLayers);
1016 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001017
1018 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1019 for(int i = 0; i < numAppLayers; i++) {
1020 if(!mCurrentFrame.isFBComposed[i]) {
1021 hwc_layer_1_t* layer = &list->hwLayers[i];
1022 if(not isSupportedForMDPComp(ctx, layer)) {
1023 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1024 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001025 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001026 return false;
1027 }
1028 }
1029 }
1030
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001031 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301032 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001033 if(!ret) {
1034 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001035 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001036 return false;
1037 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001038
1039 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001040
radhakrishnac9a67412013-09-25 17:40:42 +05301041 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001042 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301043 }
1044
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001045 //Will benefit cases where a video has non-updating background.
1046 if((mDpy > HWC_DISPLAY_PRIMARY) and
1047 (mdpCount > MAX_SEC_LAYERS)) {
1048 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001049 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001050 return false;
1051 }
1052
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001053 if(!postHeuristicsHandling(ctx, list)) {
1054 ALOGD_IF(isDebug(), "post heuristic handling failed");
1055 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001056 return false;
1057 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001058 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1059 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001060
Saurabh Shahaa236822013-04-24 18:07:26 -07001061 return true;
1062}
1063
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001064bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001065 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001066 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1067 return false;
1068
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001069 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001070 return false;
1071 }
1072
Saurabh Shahb772ae32013-11-18 15:40:02 -08001073 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001074 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1075 const int stagesForMDP = min(sMaxPipesPerMixer,
1076 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001077
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001078 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1079 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1080 int lastMDPSupportedIndex = numAppLayers;
1081 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001082
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001083 //Find the minimum MDP batch size
1084 for(int i = 0; i < numAppLayers;i++) {
1085 if(mCurrentFrame.drop[i]) {
1086 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001087 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001088 }
1089 hwc_layer_1_t* layer = &list->hwLayers[i];
1090 if(not isSupportedForMDPComp(ctx, layer)) {
1091 lastMDPSupportedIndex = i;
1092 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1093 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001094 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001095 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001096 }
1097
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001098 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1099 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1100 mCurrentFrame.dropCount);
1101
1102 //Start at a point where the fb batch should at least have 2 layers, for
1103 //this mode to be justified.
1104 while(fbBatchSize < 2) {
1105 ++fbBatchSize;
1106 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001107 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001108
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001109 //If there are no layers for MDP, this mode doesnt make sense.
1110 if(mdpBatchSize < 1) {
1111 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1112 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001113 return false;
1114 }
1115
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001116 mCurrentFrame.reset(numAppLayers);
1117
1118 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1119 while(mdpBatchSize > 0) {
1120 //Mark layers for MDP comp
1121 int mdpBatchLeft = mdpBatchSize;
1122 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1123 if(mCurrentFrame.drop[i]) {
1124 continue;
1125 }
1126 mCurrentFrame.isFBComposed[i] = false;
1127 --mdpBatchLeft;
1128 }
1129
1130 mCurrentFrame.fbZ = mdpBatchSize;
1131 mCurrentFrame.fbCount = fbBatchSize;
1132 mCurrentFrame.mdpCount = mdpBatchSize;
1133
1134 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1135 __FUNCTION__, mdpBatchSize, fbBatchSize,
1136 mCurrentFrame.dropCount);
1137
1138 if(postHeuristicsHandling(ctx, list)) {
1139 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001140 __FUNCTION__);
1141 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1142 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001143 return true;
1144 }
1145
1146 reset(ctx);
1147 --mdpBatchSize;
1148 ++fbBatchSize;
1149 }
1150
1151 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001152}
1153
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001154bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301155 if(mDpy or isSecurePresent(ctx, mDpy) or
1156 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001157 return false;
1158 }
1159 return true;
1160}
1161
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001162bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1163 hwc_display_contents_1_t* list){
1164 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1165 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1166 mDpy ) {
1167 return false;
1168 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001169 if(ctx->listStats[mDpy].secureUI)
1170 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001171 return true;
1172}
1173
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001174bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1175 hwc_display_contents_1_t* list) {
1176 const bool secureOnly = true;
1177 return videoOnlyComp(ctx, list, not secureOnly) or
1178 videoOnlyComp(ctx, list, secureOnly);
1179}
1180
1181bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001182 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001183 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1184 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001185 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001186
Saurabh Shahaa236822013-04-24 18:07:26 -07001187 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001188 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001189 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001190 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001191
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001192 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1193 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001194 return false;
1195 }
1196
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001197 /* Bail out if we are processing only secured video layers
1198 * and we dont have any */
1199 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001200 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001201 return false;
1202 }
1203
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001204 if(mCurrentFrame.fbCount)
1205 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001206
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001207 if(sEnable4k2kYUVSplit){
1208 adjustForSourceSplit(ctx, list);
1209 }
1210
1211 if(!postHeuristicsHandling(ctx, list)) {
1212 ALOGD_IF(isDebug(), "post heuristic handling failed");
1213 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001214 return false;
1215 }
1216
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001217 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1218 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001219 return true;
1220}
1221
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001222/* Checks for conditions where YUV layers cannot be bypassed */
1223bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001224 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001225 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001226 return false;
1227 }
1228
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001229 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001230 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1231 return false;
1232 }
1233
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001234 if(isSecuring(ctx, layer)) {
1235 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1236 return false;
1237 }
1238
Saurabh Shah4fdde762013-04-30 18:47:33 -07001239 if(!isValidDimension(ctx, layer)) {
1240 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1241 __FUNCTION__);
1242 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001243 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001244
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001245 if(layer->planeAlpha < 0xFF) {
1246 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1247 in video only mode",
1248 __FUNCTION__);
1249 return false;
1250 }
1251
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001252 return true;
1253}
1254
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301255/* starts at fromIndex and check for each layer to find
1256 * if it it has overlapping with any Updating layer above it in zorder
1257 * till the end of the batch. returns true if it finds any intersection */
1258bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1259 int fromIndex, int toIndex) {
1260 for(int i = fromIndex; i < toIndex; i++) {
1261 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1262 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1263 return false;
1264 }
1265 }
1266 }
1267 return true;
1268}
1269
1270/* Checks if given layer at targetLayerIndex has any
1271 * intersection with all the updating layers in beween
1272 * fromIndex and toIndex. Returns true if it finds intersectiion */
1273bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1274 int fromIndex, int toIndex, int targetLayerIndex) {
1275 for(int i = fromIndex; i <= toIndex; i++) {
1276 if(!mCurrentFrame.isFBComposed[i]) {
1277 if(areLayersIntersecting(&list->hwLayers[i],
1278 &list->hwLayers[targetLayerIndex])) {
1279 return true;
1280 }
1281 }
1282 }
1283 return false;
1284}
1285
1286int MDPComp::getBatch(hwc_display_contents_1_t* list,
1287 int& maxBatchStart, int& maxBatchEnd,
1288 int& maxBatchCount) {
1289 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301290 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001291 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301292 while (i < mCurrentFrame.layerCount) {
1293 int batchCount = 0;
1294 int batchStart = i;
1295 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001296 /* Adjust batch Z order with the dropped layers so far */
1297 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301298 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301299 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301300 while(i < mCurrentFrame.layerCount) {
1301 if(!mCurrentFrame.isFBComposed[i]) {
1302 if(!batchCount) {
1303 i++;
1304 break;
1305 }
1306 updatingLayersAbove++;
1307 i++;
1308 continue;
1309 } else {
1310 if(mCurrentFrame.drop[i]) {
1311 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001312 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301313 continue;
1314 } else if(updatingLayersAbove <= 0) {
1315 batchCount++;
1316 batchEnd = i;
1317 i++;
1318 continue;
1319 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1320
1321 // We have a valid updating layer already. If layer-i not
1322 // have overlapping with all updating layers in between
1323 // batch-start and i, then we can add layer i to batch.
1324 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1325 batchCount++;
1326 batchEnd = i;
1327 i++;
1328 continue;
1329 } else if(canPushBatchToTop(list, batchStart, i)) {
1330 //If All the non-updating layers with in this batch
1331 //does not have intersection with the updating layers
1332 //above in z-order, then we can safely move the batch to
1333 //higher z-order. Increment fbZ as it is moving up.
1334 if( firstZReverseIndex < 0) {
1335 firstZReverseIndex = i;
1336 }
1337 batchCount++;
1338 batchEnd = i;
1339 fbZ += updatingLayersAbove;
1340 i++;
1341 updatingLayersAbove = 0;
1342 continue;
1343 } else {
1344 //both failed.start the loop again from here.
1345 if(firstZReverseIndex >= 0) {
1346 i = firstZReverseIndex;
1347 }
1348 break;
1349 }
1350 }
1351 }
1352 }
1353 if(batchCount > maxBatchCount) {
1354 maxBatchCount = batchCount;
1355 maxBatchStart = batchStart;
1356 maxBatchEnd = batchEnd;
1357 fbZOrder = fbZ;
1358 }
1359 }
1360 return fbZOrder;
1361}
1362
1363bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1364 hwc_display_contents_1_t* list) {
1365 /* Idea is to keep as many non-updating(cached) layers in FB and
1366 * send rest of them through MDP. This is done in 2 steps.
1367 * 1. Find the maximum contiguous batch of non-updating layers.
1368 * 2. See if we can improve this batch size for caching by adding
1369 * opaque layers around the batch, if they don't have
1370 * any overlapping with the updating layers in between.
1371 * NEVER mark an updating layer for caching.
1372 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001373
1374 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001375 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001376 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301377 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001378
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001379 /* Nothing is cached. No batching needed */
1380 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001381 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001382 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001383
1384 /* No MDP comp layers, try to use other comp modes */
1385 if(mCurrentFrame.mdpCount == 0) {
1386 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001387 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001388
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301389 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001390
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301391 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001392 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001393 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001394 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301395 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001396 if(!mCurrentFrame.drop[i]){
1397 //If an unsupported layer is being attempted to
1398 //be pulled out we should fail
1399 if(not isSupportedForMDPComp(ctx, layer)) {
1400 return false;
1401 }
1402 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001403 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001404 }
1405 }
1406
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301407 // update the frame data
1408 mCurrentFrame.fbZ = fbZ;
1409 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001410 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001411 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001412
1413 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301414 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001415
1416 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001417}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001418
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001419void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001420 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001421 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001422 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001423
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001424 for(int i = 0; i < numAppLayers; i++) {
1425 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001426 if(!mCurrentFrame.drop[i])
1427 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001428 mCurrentFrame.isFBComposed[i] = true;
1429 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001430 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001431 }
1432 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001433
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001434 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001435 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1436 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001437
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001438 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1439 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1440 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001441}
1442
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001443void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1444 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001445 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1446 for(int index = 0;index < nYuvCount; index++){
1447 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1448 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1449
1450 if(!isYUVDoable(ctx, layer)) {
1451 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1452 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1453 mCurrentFrame.fbCount++;
1454 }
1455 } else {
1456 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001457 private_handle_t *hnd = (private_handle_t *)layer->handle;
1458 if(!secureOnly || isSecureBuffer(hnd)) {
1459 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1460 mCurrentFrame.fbCount--;
1461 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001462 }
1463 }
1464 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001465
1466 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001467 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1468 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001469 mCurrentFrame.fbCount);
1470}
1471
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001472hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1473 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001474 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001475
1476 /* Update only the region of FB needed for composition */
1477 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1478 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1479 hwc_layer_1_t* layer = &list->hwLayers[i];
1480 hwc_rect_t dst = layer->displayFrame;
1481 fbRect = getUnion(fbRect, dst);
1482 }
1483 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001484 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001485 return fbRect;
1486}
1487
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001488bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1489 hwc_display_contents_1_t* list) {
1490
1491 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001492 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001493 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1494 return false;
1495 }
1496
1497 //Limitations checks
1498 if(!hwLimitationsCheck(ctx, list)) {
1499 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1500 return false;
1501 }
1502
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001503 //Configure framebuffer first if applicable
1504 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001505 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001506 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1507 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001508 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1509 __FUNCTION__);
1510 return false;
1511 }
1512 }
1513
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001514 mCurrentFrame.map();
1515
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001516 if(!allocLayerPipes(ctx, list)) {
1517 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001518 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001519 }
1520
1521 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001522 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001523 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001524 int mdpIndex = mCurrentFrame.layerToMDP[index];
1525 hwc_layer_1_t* layer = &list->hwLayers[index];
1526
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301527 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1528 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1529 mdpNextZOrder++;
1530 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001531 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1532 cur_pipe->zOrder = mdpNextZOrder++;
1533
radhakrishnac9a67412013-09-25 17:40:42 +05301534 private_handle_t *hnd = (private_handle_t *)layer->handle;
1535 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1536 if(configure4k2kYuv(ctx, layer,
1537 mCurrentFrame.mdpToLayer[mdpIndex])
1538 != 0 ){
1539 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1540 for layer %d",__FUNCTION__, index);
1541 return false;
1542 }
1543 else{
1544 mdpNextZOrder++;
1545 }
1546 continue;
1547 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001548 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1549 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301550 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001551 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001552 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001553 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001554 }
1555
Saurabh Shaha36be922013-12-16 18:18:39 -08001556 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1557 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1558 ,__FUNCTION__, mDpy);
1559 return false;
1560 }
1561
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001562 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001563 return true;
1564}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001566bool MDPComp::resourceCheck(hwc_context_t* ctx,
1567 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001568 const bool fbUsed = mCurrentFrame.fbCount;
1569 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1570 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1571 return false;
1572 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001573 // Init rotCount to number of rotate sessions used by other displays
1574 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1575 // Count the number of rotator sessions required for current display
1576 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1577 if(!mCurrentFrame.isFBComposed[index]) {
1578 hwc_layer_1_t* layer = &list->hwLayers[index];
1579 private_handle_t *hnd = (private_handle_t *)layer->handle;
1580 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1581 rotCount++;
1582 }
1583 }
1584 }
1585 // if number of layers to rotate exceeds max rotator sessions, bail out.
1586 if(rotCount > RotMgr::MAX_ROT_SESS) {
1587 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1588 __FUNCTION__, mDpy);
1589 return false;
1590 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001591 return true;
1592}
1593
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301594bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1595 hwc_display_contents_1_t* list) {
1596
1597 //A-family hw limitation:
1598 //If a layer need alpha scaling, MDP can not support.
1599 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1600 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1601 if(!mCurrentFrame.isFBComposed[i] &&
1602 isAlphaScaled( &list->hwLayers[i])) {
1603 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1604 return false;
1605 }
1606 }
1607 }
1608
1609 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1610 //If multiple layers requires downscaling and also they are overlapping
1611 //fall back to GPU since MDSS can not handle it.
1612 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1613 qdutils::MDPVersion::getInstance().is8x26()) {
1614 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1615 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1616 if(!mCurrentFrame.isFBComposed[i] &&
1617 isDownscaleRequired(botLayer)) {
1618 //if layer-i is marked for MDP and needs downscaling
1619 //check if any MDP layer on top of i & overlaps with layer-i
1620 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1621 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1622 if(!mCurrentFrame.isFBComposed[j] &&
1623 isDownscaleRequired(topLayer)) {
1624 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1625 topLayer->displayFrame);
1626 if(isValidRect(r))
1627 return false;
1628 }
1629 }
1630 }
1631 }
1632 }
1633 return true;
1634}
1635
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001636int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001637 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001638 char property[PROPERTY_VALUE_MAX];
1639
Raj Kamal4393eaa2014-06-06 13:45:20 +05301640 if(!ctx || !list) {
1641 ALOGE("%s: Invalid context or list",__FUNCTION__);
1642 mCachedFrame.reset();
1643 return -1;
1644 }
1645
1646 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1647
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001648 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1649 int currentFlags = atoi(property);
1650 if(currentFlags != sSimulationFlags) {
1651 sSimulationFlags = currentFlags;
1652 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1653 sSimulationFlags, sSimulationFlags);
1654 }
1655 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001656 // reset PTOR
1657 if(!mDpy)
1658 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001659
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301660 //Do not cache the information for next draw cycle.
1661 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1662 ALOGI("%s: Unsupported layer count for mdp composition",
1663 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001664 mCachedFrame.reset();
1665 return -1;
1666 }
1667
Saurabh Shahb39f8152013-08-22 10:21:44 -07001668 //reset old data
1669 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001670 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1671 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301672
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001673 // Detect the start of animation and fall back to GPU only once to cache
1674 // all the layers in FB and display FB content untill animation completes.
1675 if(ctx->listStats[mDpy].isDisplayAnimating) {
1676 mCurrentFrame.needsRedraw = false;
1677 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1678 mCurrentFrame.needsRedraw = true;
1679 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1680 }
1681 setMDPCompLayerFlags(ctx, list);
1682 mCachedFrame.updateCounts(mCurrentFrame);
1683 ret = -1;
1684 return ret;
1685 } else {
1686 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1687 }
1688
Saurabh Shahb39f8152013-08-22 10:21:44 -07001689 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001690 if(isFrameDoable(ctx)) {
1691 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001692
Raj Kamal4393eaa2014-06-06 13:45:20 +05301693 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1694 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001695 setMDPCompLayerFlags(ctx, list);
1696 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001697 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001698 reset(ctx);
1699 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1700 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001701 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001702 }
1703 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001704 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1705 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001706 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001707 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001708
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001709 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001710 ALOGD("GEOMETRY change: %d",
1711 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001712 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001713 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001714 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001715 }
1716
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001717 mCachedFrame.cacheAll(list);
1718 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001719 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001720}
1721
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001722bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301723
1724 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301725 int mdpIndex = mCurrentFrame.layerToMDP[index];
1726 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1727 info.pipeInfo = new MdpYUVPipeInfo;
1728 info.rot = NULL;
1729 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301730
1731 pipe_info.lIndex = ovutils::OV_INVALID;
1732 pipe_info.rIndex = ovutils::OV_INVALID;
1733
Saurabh Shahc62f3982014-03-05 14:28:26 -08001734 Overlay::PipeSpecs pipeSpecs;
1735 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1736 pipeSpecs.needsScaling = true;
1737 pipeSpecs.dpy = mDpy;
1738 pipeSpecs.fb = false;
1739
1740 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301741 if(pipe_info.lIndex == ovutils::OV_INVALID){
1742 bRet = false;
1743 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1744 __FUNCTION__);
1745 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001746 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301747 if(pipe_info.rIndex == ovutils::OV_INVALID){
1748 bRet = false;
1749 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1750 __FUNCTION__);
1751 }
1752 return bRet;
1753}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001754
1755int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1756 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001757 if (ctx->mPtorInfo.isActive()) {
1758 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001759 if (fd < 0) {
1760 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001761 }
1762 }
1763 return fd;
1764}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001765//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001766
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001767void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301768 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001769 //If 4k2k Yuv layer split is possible, and if
1770 //fbz is above 4k2k layer, increment fb zorder by 1
1771 //as we split 4k2k layer and increment zorder for right half
1772 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001773 if(!ctx)
1774 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001775 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301776 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1777 index++) {
1778 if(!mCurrentFrame.isFBComposed[index]) {
1779 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1780 mdpNextZOrder++;
1781 }
1782 mdpNextZOrder++;
1783 hwc_layer_1_t* layer = &list->hwLayers[index];
1784 private_handle_t *hnd = (private_handle_t *)layer->handle;
1785 if(is4kx2kYuvBuffer(hnd)) {
1786 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1787 mCurrentFrame.fbZ += 1;
1788 mdpNextZOrder++;
1789 //As we split 4kx2k yuv layer and program to 2 VG pipes
1790 //(if available) increase mdpcount by 1.
1791 mCurrentFrame.mdpCount++;
1792 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001793 }
1794 }
1795 }
radhakrishnac9a67412013-09-25 17:40:42 +05301796}
1797
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001798/*
1799 * Configures pipe(s) for MDP composition
1800 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001801int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001802 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001803 MdpPipeInfoNonSplit& mdp_info =
1804 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001805 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1806 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1807 eIsFg isFg = IS_FG_OFF;
1808 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001809
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1811 __FUNCTION__, layer, zOrder, dest);
1812
Saurabh Shah88e4d272013-09-03 13:31:29 -07001813 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001815}
1816
Saurabh Shah88e4d272013-09-03 13:31:29 -07001817bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001818 hwc_display_contents_1_t* list) {
1819 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001820
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001821 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001822
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001823 hwc_layer_1_t* layer = &list->hwLayers[index];
1824 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301825 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001826 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301827 continue;
1828 }
1829 }
1830
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001831 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001832 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001833 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001834 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001835 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001836
Saurabh Shahc62f3982014-03-05 14:28:26 -08001837 Overlay::PipeSpecs pipeSpecs;
1838 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1839 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1840 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1841 (qdutils::MDPVersion::getInstance().is8x26() and
1842 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1843 pipeSpecs.dpy = mDpy;
1844 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001845 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001846
Saurabh Shahc62f3982014-03-05 14:28:26 -08001847 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1848
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001849 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001850 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001851 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001852 }
1853 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001854 return true;
1855}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001856
radhakrishnac9a67412013-09-25 17:40:42 +05301857int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1858 PipeLayerPair& PipeLayerPair) {
1859 MdpYUVPipeInfo& mdp_info =
1860 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1861 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1862 eIsFg isFg = IS_FG_OFF;
1863 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1864 eDest lDest = mdp_info.lIndex;
1865 eDest rDest = mdp_info.rIndex;
1866
1867 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1868 lDest, rDest, &PipeLayerPair.rot);
1869}
1870
Saurabh Shah88e4d272013-09-03 13:31:29 -07001871bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001872
Raj Kamal4393eaa2014-06-06 13:45:20 +05301873 if(!isEnabled() or !mModeOn) {
1874 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301875 return true;
1876 }
1877
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001878 // Set the Handle timeout to true for MDP or MIXED composition.
1879 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1880 sHandleTimeout = true;
1881 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001882
1883 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001884 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001885
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001886 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1887 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001888 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001889 if(mCurrentFrame.isFBComposed[i]) continue;
1890
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001891 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001892 private_handle_t *hnd = (private_handle_t *)layer->handle;
1893 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001894 if (!(layer->flags & HWC_COLOR_FILL)) {
1895 ALOGE("%s handle null", __FUNCTION__);
1896 return false;
1897 }
1898 // No PLAY for Color layer
1899 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1900 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001901 }
1902
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001903 int mdpIndex = mCurrentFrame.layerToMDP[i];
1904
radhakrishnac9a67412013-09-25 17:40:42 +05301905 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1906 {
1907 MdpYUVPipeInfo& pipe_info =
1908 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1909 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1910 ovutils::eDest indexL = pipe_info.lIndex;
1911 ovutils::eDest indexR = pipe_info.rIndex;
1912 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301913 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301914 if(rot) {
1915 rot->queueBuffer(fd, offset);
1916 fd = rot->getDstMemId();
1917 offset = rot->getDstOffset();
1918 }
1919 if(indexL != ovutils::OV_INVALID) {
1920 ovutils::eDest destL = (ovutils::eDest)indexL;
1921 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1922 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1923 if (!ov.queueBuffer(fd, offset, destL)) {
1924 ALOGE("%s: queueBuffer failed for display:%d",
1925 __FUNCTION__, mDpy);
1926 return false;
1927 }
1928 }
1929
1930 if(indexR != ovutils::OV_INVALID) {
1931 ovutils::eDest destR = (ovutils::eDest)indexR;
1932 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1933 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1934 if (!ov.queueBuffer(fd, offset, destR)) {
1935 ALOGE("%s: queueBuffer failed for display:%d",
1936 __FUNCTION__, mDpy);
1937 return false;
1938 }
1939 }
1940 }
1941 else{
1942 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001943 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301944 ovutils::eDest dest = pipe_info.index;
1945 if(dest == ovutils::OV_INVALID) {
1946 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001947 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301948 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001949
radhakrishnac9a67412013-09-25 17:40:42 +05301950 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1951 continue;
1952 }
1953
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001954 int fd = hnd->fd;
1955 uint32_t offset = (uint32_t)hnd->offset;
1956 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1957 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001958 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001959 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001960 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001961 }
1962
radhakrishnac9a67412013-09-25 17:40:42 +05301963 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1964 using pipe: %d", __FUNCTION__, layer,
1965 hnd, dest );
1966
radhakrishnac9a67412013-09-25 17:40:42 +05301967 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1968 if(rot) {
1969 if(!rot->queueBuffer(fd, offset))
1970 return false;
1971 fd = rot->getDstMemId();
1972 offset = rot->getDstOffset();
1973 }
1974
1975 if (!ov.queueBuffer(fd, offset, dest)) {
1976 ALOGE("%s: queueBuffer failed for display:%d ",
1977 __FUNCTION__, mDpy);
1978 return false;
1979 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001980 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001981
1982 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001983 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001984 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001985}
1986
Saurabh Shah88e4d272013-09-03 13:31:29 -07001987//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001988
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001989void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301990 hwc_display_contents_1_t* list){
1991 //if 4kx2k yuv layer is totally present in either in left half
1992 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301993 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301994 if(mCurrentFrame.fbZ >= 0) {
1995 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1996 index++) {
1997 if(!mCurrentFrame.isFBComposed[index]) {
1998 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1999 mdpNextZOrder++;
2000 }
2001 mdpNextZOrder++;
2002 hwc_layer_1_t* layer = &list->hwLayers[index];
2003 private_handle_t *hnd = (private_handle_t *)layer->handle;
2004 if(is4kx2kYuvBuffer(hnd)) {
2005 hwc_rect_t dst = layer->displayFrame;
2006 if((dst.left > lSplit) || (dst.right < lSplit)) {
2007 mCurrentFrame.mdpCount += 1;
2008 }
2009 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2010 mCurrentFrame.fbZ += 1;
2011 mdpNextZOrder++;
2012 }
2013 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002014 }
radhakrishnac9a67412013-09-25 17:40:42 +05302015 }
2016}
2017
Saurabh Shah88e4d272013-09-03 13:31:29 -07002018bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002019 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002020
Saurabh Shahc62f3982014-03-05 14:28:26 -08002021 const int lSplit = getLeftSplit(ctx, mDpy);
2022 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002023 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002024 pipe_info.lIndex = ovutils::OV_INVALID;
2025 pipe_info.rIndex = ovutils::OV_INVALID;
2026
Saurabh Shahc62f3982014-03-05 14:28:26 -08002027 Overlay::PipeSpecs pipeSpecs;
2028 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2029 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2030 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2031 pipeSpecs.dpy = mDpy;
2032 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2033 pipeSpecs.fb = false;
2034
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002035 // Acquire pipe only for the updating half
2036 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2037 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2038
2039 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002040 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002041 if(pipe_info.lIndex == ovutils::OV_INVALID)
2042 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002043 }
2044
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002045 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002046 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2047 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002048 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002049 return false;
2050 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002051
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002052 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002053}
2054
Saurabh Shah88e4d272013-09-03 13:31:29 -07002055bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002056 hwc_display_contents_1_t* list) {
2057 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002058
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002059 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002060
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002061 hwc_layer_1_t* layer = &list->hwLayers[index];
2062 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302063 hwc_rect_t dst = layer->displayFrame;
2064 const int lSplit = getLeftSplit(ctx, mDpy);
2065 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
2066 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002067 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302068 continue;
2069 }
2070 }
2071 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002072 int mdpIndex = mCurrentFrame.layerToMDP[index];
2073 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002074 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002075 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002076 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002077
Saurabh Shahc62f3982014-03-05 14:28:26 -08002078 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2079 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2080 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002081 return false;
2082 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002083 }
2084 return true;
2085}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002086
radhakrishnac9a67412013-09-25 17:40:42 +05302087int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2088 PipeLayerPair& PipeLayerPair) {
2089 const int lSplit = getLeftSplit(ctx, mDpy);
2090 hwc_rect_t dst = layer->displayFrame;
2091 if((dst.left > lSplit)||(dst.right < lSplit)){
2092 MdpYUVPipeInfo& mdp_info =
2093 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2094 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2095 eIsFg isFg = IS_FG_OFF;
2096 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2097 eDest lDest = mdp_info.lIndex;
2098 eDest rDest = mdp_info.rIndex;
2099
2100 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2101 lDest, rDest, &PipeLayerPair.rot);
2102 }
2103 else{
2104 return configure(ctx, layer, PipeLayerPair);
2105 }
2106}
2107
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002108/*
2109 * Configures pipe(s) for MDP composition
2110 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002111int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002112 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002113 MdpPipeInfoSplit& mdp_info =
2114 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002115 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2116 eIsFg isFg = IS_FG_OFF;
2117 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2118 eDest lDest = mdp_info.lIndex;
2119 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002120
2121 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2122 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2123
Saurabh Shah88e4d272013-09-03 13:31:29 -07002124 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002125 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002126}
2127
Saurabh Shah88e4d272013-09-03 13:31:29 -07002128bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002129
Raj Kamal4393eaa2014-06-06 13:45:20 +05302130 if(!isEnabled() or !mModeOn) {
2131 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302132 return true;
2133 }
2134
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002135 // Set the Handle timeout to true for MDP or MIXED composition.
2136 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2137 sHandleTimeout = true;
2138 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002139
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002140 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002141 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002142
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002143 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2144 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002145 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002146 if(mCurrentFrame.isFBComposed[i]) continue;
2147
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002148 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002149 private_handle_t *hnd = (private_handle_t *)layer->handle;
2150 if(!hnd) {
2151 ALOGE("%s handle null", __FUNCTION__);
2152 return false;
2153 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002154
2155 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2156 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002157 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002158
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002159 int mdpIndex = mCurrentFrame.layerToMDP[i];
2160
radhakrishnac9a67412013-09-25 17:40:42 +05302161 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2162 {
2163 MdpYUVPipeInfo& pipe_info =
2164 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2165 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2166 ovutils::eDest indexL = pipe_info.lIndex;
2167 ovutils::eDest indexR = pipe_info.rIndex;
2168 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302169 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302170 if(rot) {
2171 rot->queueBuffer(fd, offset);
2172 fd = rot->getDstMemId();
2173 offset = rot->getDstOffset();
2174 }
2175 if(indexL != ovutils::OV_INVALID) {
2176 ovutils::eDest destL = (ovutils::eDest)indexL;
2177 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2178 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2179 if (!ov.queueBuffer(fd, offset, destL)) {
2180 ALOGE("%s: queueBuffer failed for display:%d",
2181 __FUNCTION__, mDpy);
2182 return false;
2183 }
2184 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002185
radhakrishnac9a67412013-09-25 17:40:42 +05302186 if(indexR != ovutils::OV_INVALID) {
2187 ovutils::eDest destR = (ovutils::eDest)indexR;
2188 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2189 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2190 if (!ov.queueBuffer(fd, offset, destR)) {
2191 ALOGE("%s: queueBuffer failed for display:%d",
2192 __FUNCTION__, mDpy);
2193 return false;
2194 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002195 }
2196 }
radhakrishnac9a67412013-09-25 17:40:42 +05302197 else{
2198 MdpPipeInfoSplit& pipe_info =
2199 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2200 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002201
radhakrishnac9a67412013-09-25 17:40:42 +05302202 ovutils::eDest indexL = pipe_info.lIndex;
2203 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002204
radhakrishnac9a67412013-09-25 17:40:42 +05302205 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002206 uint32_t offset = (uint32_t)hnd->offset;
2207 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2208 if (!mDpy && (index != -1)) {
2209 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2210 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002211 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002212 }
radhakrishnac9a67412013-09-25 17:40:42 +05302213
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002214 if(ctx->mAD->draw(ctx, fd, offset)) {
2215 fd = ctx->mAD->getDstFd();
2216 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002217 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002218
radhakrishnac9a67412013-09-25 17:40:42 +05302219 if(rot) {
2220 rot->queueBuffer(fd, offset);
2221 fd = rot->getDstMemId();
2222 offset = rot->getDstOffset();
2223 }
2224
2225 //************* play left mixer **********
2226 if(indexL != ovutils::OV_INVALID) {
2227 ovutils::eDest destL = (ovutils::eDest)indexL;
2228 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2229 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2230 if (!ov.queueBuffer(fd, offset, destL)) {
2231 ALOGE("%s: queueBuffer failed for left mixer",
2232 __FUNCTION__);
2233 return false;
2234 }
2235 }
2236
2237 //************* play right mixer **********
2238 if(indexR != ovutils::OV_INVALID) {
2239 ovutils::eDest destR = (ovutils::eDest)indexR;
2240 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2241 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2242 if (!ov.queueBuffer(fd, offset, destR)) {
2243 ALOGE("%s: queueBuffer failed for right mixer",
2244 __FUNCTION__);
2245 return false;
2246 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002247 }
2248 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002249
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002250 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2251 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002252
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002253 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002254}
Saurabh Shahab47c692014-02-12 18:45:57 -08002255
2256//================MDPCompSrcSplit==============================================
2257bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002258 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002259 private_handle_t *hnd = (private_handle_t *)layer->handle;
2260 hwc_rect_t dst = layer->displayFrame;
2261 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2262 pipe_info.lIndex = ovutils::OV_INVALID;
2263 pipe_info.rIndex = ovutils::OV_INVALID;
2264
2265 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2266 //should have a higher priority than the right one. Pipe priorities are
2267 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002268
Saurabh Shahc62f3982014-03-05 14:28:26 -08002269 Overlay::PipeSpecs pipeSpecs;
2270 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2271 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2272 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2273 pipeSpecs.dpy = mDpy;
2274 pipeSpecs.fb = false;
2275
Saurabh Shahab47c692014-02-12 18:45:57 -08002276 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002277 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002278 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002279 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002280 }
2281
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002282 /* Use 2 pipes IF
2283 a) Layer's crop width is > 2048 or
2284 b) Layer's dest width > 2048 or
2285 c) On primary, driver has indicated with caps to split always. This is
2286 based on an empirically derived value of panel height. Applied only
2287 if the layer's width is > mixer's width
2288 */
2289
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302290 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002291 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302292 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002293 int lSplit = getLeftSplit(ctx, mDpy);
2294 int dstWidth = dst.right - dst.left;
2295 int cropWidth = crop.right - crop.left;
2296
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302297 if(dstWidth > mdpHw.getMaxMixerWidth() or
2298 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002299 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002300 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002301 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002302 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002303 }
2304
2305 // Return values
2306 // 1 Left pipe is higher priority, do nothing.
2307 // 0 Pipes of same priority.
2308 //-1 Right pipe is of higher priority, needs swap.
2309 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2310 pipe_info.rIndex) == -1) {
2311 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002312 }
2313 }
2314
2315 return true;
2316}
2317
Saurabh Shahab47c692014-02-12 18:45:57 -08002318int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2319 PipeLayerPair& PipeLayerPair) {
2320 private_handle_t *hnd = (private_handle_t *)layer->handle;
2321 if(!hnd) {
2322 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2323 return -1;
2324 }
2325 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2326 MdpPipeInfoSplit& mdp_info =
2327 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2328 Rotator **rot = &PipeLayerPair.rot;
2329 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2330 eIsFg isFg = IS_FG_OFF;
2331 eDest lDest = mdp_info.lIndex;
2332 eDest rDest = mdp_info.rIndex;
2333 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2334 hwc_rect_t dst = layer->displayFrame;
2335 int transform = layer->transform;
2336 eTransform orient = static_cast<eTransform>(transform);
2337 const int downscale = 0;
2338 int rotFlags = ROT_FLAGS_NONE;
2339 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2340 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2341
2342 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2343 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2344
2345 // Handle R/B swap
2346 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2347 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2348 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2349 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2350 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2351 }
2352
Saurabh Shah97e2d802014-04-14 18:03:54 -07002353 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002354 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002355
2356 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2357 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002358 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002359 }
2360
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002361 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002362 (*rot) = ctx->mRotMgr->getNext();
2363 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002364 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002365 //If the video is using a single pipe, enable BWC
2366 if(rDest == OV_INVALID) {
2367 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2368 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002369 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002370 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002371 ALOGE("%s: configRotator failed!", __FUNCTION__);
2372 return -1;
2373 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002374 updateSource(orient, whf, crop, *rot);
Saurabh Shahab47c692014-02-12 18:45:57 -08002375 rotFlags |= ROT_PREROTATED;
2376 }
2377
2378 //If 2 pipes being used, divide layer into half, crop and dst
2379 hwc_rect_t cropL = crop;
2380 hwc_rect_t cropR = crop;
2381 hwc_rect_t dstL = dst;
2382 hwc_rect_t dstR = dst;
2383 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2384 cropL.right = (crop.right + crop.left) / 2;
2385 cropR.left = cropL.right;
2386 sanitizeSourceCrop(cropL, cropR, hnd);
2387
2388 //Swap crops on H flip since 2 pipes are being used
2389 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2390 hwc_rect_t tmp = cropL;
2391 cropL = cropR;
2392 cropR = tmp;
2393 }
2394
2395 dstL.right = (dst.right + dst.left) / 2;
2396 dstR.left = dstL.right;
2397 }
2398
2399 //For the mdp, since either we are pre-rotating or MDP does flips
2400 orient = OVERLAY_TRANSFORM_0;
2401 transform = 0;
2402
2403 //configure left pipe
2404 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002405 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002406 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2407 (ovutils::eBlending) getBlending(layer->blending));
2408
2409 if(configMdp(ctx->mOverlay, pargL, orient,
2410 cropL, dstL, metadata, lDest) < 0) {
2411 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2412 return -1;
2413 }
2414 }
2415
2416 //configure right pipe
2417 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002418 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002419 static_cast<eRotFlags>(rotFlags),
2420 layer->planeAlpha,
2421 (ovutils::eBlending) getBlending(layer->blending));
2422 if(configMdp(ctx->mOverlay, pargR, orient,
2423 cropR, dstR, metadata, rDest) < 0) {
2424 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2425 return -1;
2426 }
2427 }
2428
2429 return 0;
2430}
2431
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002432}; //namespace
2433