blob: 77bc0b554c55dd3ab9e15d1098d6da003813ed8d [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;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = 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))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530162 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530163 }
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
Raj Kamal389d6e32014-08-04 14:43:24 +0530776 if(sEnableYUVsplit){
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
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700803 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700804 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
Xu Yangcda012c2014-07-30 21:57:21 +0800910 // Store the blending mode, planeAlpha, and transform of PTOR layers
911 int32_t blending[numPTORLayersFound];
912 uint8_t planeAlpha[numPTORLayersFound];
913 uint32_t transform[numPTORLayersFound];
914
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700915 for(int j = 0; j < numPTORLayersFound; j++) {
916 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700917
918 // Update src crop of PTOR layer
919 hwc_layer_1_t* layer = &list->hwLayers[index];
920 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
921 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
922 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
923 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
924
925 // Store & update w, h, format of PTOR layer
926 private_handle_t *hnd = (private_handle_t *)layer->handle;
927 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
928 layerWhf[j] = whf;
929 hnd->width = renderBuf->width;
930 hnd->height = renderBuf->height;
931 hnd->format = renderBuf->format;
932
Xu Yangcda012c2014-07-30 21:57:21 +0800933 // Store & update blending mode, planeAlpha and transform of PTOR layer
934 blending[j] = layer->blending;
935 planeAlpha[j] = layer->planeAlpha;
936 transform[j] = layer->transform;
937 layer->blending = HWC_BLENDING_NONE;
938 layer->planeAlpha = 0xFF;
939 layer->transform = 0;
940
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700941 // Remove overlap from crop & displayFrame of below layers
942 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700943 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 if(!isValidRect(getIntersection(layer->displayFrame,
945 overlapRect[j]))) {
946 continue;
947 }
948 // Update layer attributes
949 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
950 hwc_rect_t destRect = deductRect(layer->displayFrame,
951 overlapRect[j]);
952 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
953 layer->transform);
954 layer->sourceCropf.left = (float)srcCrop.left;
955 layer->sourceCropf.top = (float)srcCrop.top;
956 layer->sourceCropf.right = (float)srcCrop.right;
957 layer->sourceCropf.bottom = (float)srcCrop.bottom;
958 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959 }
960
961 mCurrentFrame.mdpCount = numAppLayers;
962 mCurrentFrame.fbCount = 0;
963 mCurrentFrame.fbZ = -1;
964
965 for (int j = 0; j < numAppLayers; j++)
966 mCurrentFrame.isFBComposed[j] = false;
967
968 bool result = postHeuristicsHandling(ctx, list);
969
970 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700971 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700972 hwc_layer_1_t* layer = &list->hwLayers[i];
973 layer->displayFrame = displayFrame[i];
974 layer->sourceCropf.left = (float)sourceCrop[i].left;
975 layer->sourceCropf.top = (float)sourceCrop[i].top;
976 layer->sourceCropf.right = (float)sourceCrop[i].right;
977 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
978 }
979
Xu Yangcda012c2014-07-30 21:57:21 +0800980 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700981 for (int i = 0; i < numPTORLayersFound; i++) {
982 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +0800983 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700984 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
985 hnd->width = layerWhf[i].w;
986 hnd->height = layerWhf[i].h;
987 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +0800988 layer->blending = blending[i];
989 layer->planeAlpha = planeAlpha[i];
990 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700991 }
992
Sushil Chauhandefd3522014-05-13 18:17:12 -0700993 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700994 // reset PTOR
995 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700996 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700997 } else {
998 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
999 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001000 }
1001
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001002 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1003 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001004 return result;
1005}
1006
Saurabh Shahaa236822013-04-24 18:07:26 -07001007bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1008{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001009 if(!sEnableMixedMode) {
1010 //Mixed mode is disabled. No need to even try caching.
1011 return false;
1012 }
1013
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001014 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001015 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001016 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001017 cacheBasedComp(ctx, list);
1018 } else {
1019 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001020 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001021 }
1022
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001023 return ret;
1024}
1025
1026bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1027 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001028 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1029 return false;
1030
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001031 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001032 mCurrentFrame.reset(numAppLayers);
1033 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001034
1035 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1036 for(int i = 0; i < numAppLayers; i++) {
1037 if(!mCurrentFrame.isFBComposed[i]) {
1038 hwc_layer_1_t* layer = &list->hwLayers[i];
1039 if(not isSupportedForMDPComp(ctx, layer)) {
1040 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1041 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001042 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001043 return false;
1044 }
1045 }
1046 }
1047
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001048 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301049 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001050 if(!ret) {
1051 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001052 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001053 return false;
1054 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001055
1056 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001057
Raj Kamal389d6e32014-08-04 14:43:24 +05301058 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001059 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301060 }
1061
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001062 //Will benefit cases where a video has non-updating background.
1063 if((mDpy > HWC_DISPLAY_PRIMARY) and
1064 (mdpCount > MAX_SEC_LAYERS)) {
1065 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001066 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001067 return false;
1068 }
1069
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001070 if(!postHeuristicsHandling(ctx, list)) {
1071 ALOGD_IF(isDebug(), "post heuristic handling failed");
1072 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001073 return false;
1074 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001075 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1076 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001077
Saurabh Shahaa236822013-04-24 18:07:26 -07001078 return true;
1079}
1080
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001081bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001082 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001083 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1084 return false;
1085
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001086 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001087 return false;
1088 }
1089
Saurabh Shahb772ae32013-11-18 15:40:02 -08001090 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001091 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1092 const int stagesForMDP = min(sMaxPipesPerMixer,
1093 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001094
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001095 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1096 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1097 int lastMDPSupportedIndex = numAppLayers;
1098 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001099
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001100 //Find the minimum MDP batch size
1101 for(int i = 0; i < numAppLayers;i++) {
1102 if(mCurrentFrame.drop[i]) {
1103 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001104 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001105 }
1106 hwc_layer_1_t* layer = &list->hwLayers[i];
1107 if(not isSupportedForMDPComp(ctx, layer)) {
1108 lastMDPSupportedIndex = i;
1109 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1110 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001111 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001112 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001113 }
1114
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001115 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1116 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1117 mCurrentFrame.dropCount);
1118
1119 //Start at a point where the fb batch should at least have 2 layers, for
1120 //this mode to be justified.
1121 while(fbBatchSize < 2) {
1122 ++fbBatchSize;
1123 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001124 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001125
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001126 //If there are no layers for MDP, this mode doesnt make sense.
1127 if(mdpBatchSize < 1) {
1128 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1129 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001130 return false;
1131 }
1132
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001133 mCurrentFrame.reset(numAppLayers);
1134
1135 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1136 while(mdpBatchSize > 0) {
1137 //Mark layers for MDP comp
1138 int mdpBatchLeft = mdpBatchSize;
1139 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1140 if(mCurrentFrame.drop[i]) {
1141 continue;
1142 }
1143 mCurrentFrame.isFBComposed[i] = false;
1144 --mdpBatchLeft;
1145 }
1146
1147 mCurrentFrame.fbZ = mdpBatchSize;
1148 mCurrentFrame.fbCount = fbBatchSize;
1149 mCurrentFrame.mdpCount = mdpBatchSize;
1150
1151 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1152 __FUNCTION__, mdpBatchSize, fbBatchSize,
1153 mCurrentFrame.dropCount);
1154
1155 if(postHeuristicsHandling(ctx, list)) {
1156 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001157 __FUNCTION__);
1158 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1159 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001160 return true;
1161 }
1162
1163 reset(ctx);
1164 --mdpBatchSize;
1165 ++fbBatchSize;
1166 }
1167
1168 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001169}
1170
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001171bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301172 if(mDpy or isSecurePresent(ctx, mDpy) or
1173 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001174 return false;
1175 }
1176 return true;
1177}
1178
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001179bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1180 hwc_display_contents_1_t* list){
1181 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1182 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1183 mDpy ) {
1184 return false;
1185 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001186 if(ctx->listStats[mDpy].secureUI)
1187 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001188 return true;
1189}
1190
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001191bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1192 hwc_display_contents_1_t* list) {
1193 const bool secureOnly = true;
1194 return videoOnlyComp(ctx, list, not secureOnly) or
1195 videoOnlyComp(ctx, list, secureOnly);
1196}
1197
1198bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001199 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001200 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1201 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001202 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001203
Saurabh Shahaa236822013-04-24 18:07:26 -07001204 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001205 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001206 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001207 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001208
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001209 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1210 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001211 return false;
1212 }
1213
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001214 /* Bail out if we are processing only secured video layers
1215 * and we dont have any */
1216 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001217 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001218 return false;
1219 }
1220
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001221 if(mCurrentFrame.fbCount)
1222 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001223
Raj Kamal389d6e32014-08-04 14:43:24 +05301224 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001225 adjustForSourceSplit(ctx, list);
1226 }
1227
1228 if(!postHeuristicsHandling(ctx, list)) {
1229 ALOGD_IF(isDebug(), "post heuristic handling failed");
1230 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001231 return false;
1232 }
1233
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001234 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1235 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001236 return true;
1237}
1238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001239/* Checks for conditions where YUV layers cannot be bypassed */
1240bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001241 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001242 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001243 return false;
1244 }
1245
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001246 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001247 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1248 return false;
1249 }
1250
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001251 if(isSecuring(ctx, layer)) {
1252 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1253 return false;
1254 }
1255
Saurabh Shah4fdde762013-04-30 18:47:33 -07001256 if(!isValidDimension(ctx, layer)) {
1257 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1258 __FUNCTION__);
1259 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001260 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001261
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001262 if(layer->planeAlpha < 0xFF) {
1263 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1264 in video only mode",
1265 __FUNCTION__);
1266 return false;
1267 }
1268
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001269 return true;
1270}
1271
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301272/* starts at fromIndex and check for each layer to find
1273 * if it it has overlapping with any Updating layer above it in zorder
1274 * till the end of the batch. returns true if it finds any intersection */
1275bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1276 int fromIndex, int toIndex) {
1277 for(int i = fromIndex; i < toIndex; i++) {
1278 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1279 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1280 return false;
1281 }
1282 }
1283 }
1284 return true;
1285}
1286
1287/* Checks if given layer at targetLayerIndex has any
1288 * intersection with all the updating layers in beween
1289 * fromIndex and toIndex. Returns true if it finds intersectiion */
1290bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1291 int fromIndex, int toIndex, int targetLayerIndex) {
1292 for(int i = fromIndex; i <= toIndex; i++) {
1293 if(!mCurrentFrame.isFBComposed[i]) {
1294 if(areLayersIntersecting(&list->hwLayers[i],
1295 &list->hwLayers[targetLayerIndex])) {
1296 return true;
1297 }
1298 }
1299 }
1300 return false;
1301}
1302
1303int MDPComp::getBatch(hwc_display_contents_1_t* list,
1304 int& maxBatchStart, int& maxBatchEnd,
1305 int& maxBatchCount) {
1306 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301307 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001308 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301309 while (i < mCurrentFrame.layerCount) {
1310 int batchCount = 0;
1311 int batchStart = i;
1312 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001313 /* Adjust batch Z order with the dropped layers so far */
1314 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301315 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301316 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301317 while(i < mCurrentFrame.layerCount) {
1318 if(!mCurrentFrame.isFBComposed[i]) {
1319 if(!batchCount) {
1320 i++;
1321 break;
1322 }
1323 updatingLayersAbove++;
1324 i++;
1325 continue;
1326 } else {
1327 if(mCurrentFrame.drop[i]) {
1328 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001329 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301330 continue;
1331 } else if(updatingLayersAbove <= 0) {
1332 batchCount++;
1333 batchEnd = i;
1334 i++;
1335 continue;
1336 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1337
1338 // We have a valid updating layer already. If layer-i not
1339 // have overlapping with all updating layers in between
1340 // batch-start and i, then we can add layer i to batch.
1341 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1342 batchCount++;
1343 batchEnd = i;
1344 i++;
1345 continue;
1346 } else if(canPushBatchToTop(list, batchStart, i)) {
1347 //If All the non-updating layers with in this batch
1348 //does not have intersection with the updating layers
1349 //above in z-order, then we can safely move the batch to
1350 //higher z-order. Increment fbZ as it is moving up.
1351 if( firstZReverseIndex < 0) {
1352 firstZReverseIndex = i;
1353 }
1354 batchCount++;
1355 batchEnd = i;
1356 fbZ += updatingLayersAbove;
1357 i++;
1358 updatingLayersAbove = 0;
1359 continue;
1360 } else {
1361 //both failed.start the loop again from here.
1362 if(firstZReverseIndex >= 0) {
1363 i = firstZReverseIndex;
1364 }
1365 break;
1366 }
1367 }
1368 }
1369 }
1370 if(batchCount > maxBatchCount) {
1371 maxBatchCount = batchCount;
1372 maxBatchStart = batchStart;
1373 maxBatchEnd = batchEnd;
1374 fbZOrder = fbZ;
1375 }
1376 }
1377 return fbZOrder;
1378}
1379
1380bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1381 hwc_display_contents_1_t* list) {
1382 /* Idea is to keep as many non-updating(cached) layers in FB and
1383 * send rest of them through MDP. This is done in 2 steps.
1384 * 1. Find the maximum contiguous batch of non-updating layers.
1385 * 2. See if we can improve this batch size for caching by adding
1386 * opaque layers around the batch, if they don't have
1387 * any overlapping with the updating layers in between.
1388 * NEVER mark an updating layer for caching.
1389 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001390
1391 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001392 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001393 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301394 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001395
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001396 /* Nothing is cached. No batching needed */
1397 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001398 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001399 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001400
1401 /* No MDP comp layers, try to use other comp modes */
1402 if(mCurrentFrame.mdpCount == 0) {
1403 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001404 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001405
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301406 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001407
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301408 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001409 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001410 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001411 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301412 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001413 if(!mCurrentFrame.drop[i]){
1414 //If an unsupported layer is being attempted to
1415 //be pulled out we should fail
1416 if(not isSupportedForMDPComp(ctx, layer)) {
1417 return false;
1418 }
1419 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001420 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001421 }
1422 }
1423
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301424 // update the frame data
1425 mCurrentFrame.fbZ = fbZ;
1426 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001427 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001428 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001429
1430 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301431 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001432
1433 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001434}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001435
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001436void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001437 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001438 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001439 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001440
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001441 for(int i = 0; i < numAppLayers; i++) {
1442 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001443 if(!mCurrentFrame.drop[i])
1444 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001445 mCurrentFrame.isFBComposed[i] = true;
1446 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001447 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001448 }
1449 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001450
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001451 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001452 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1453 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001454
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001455 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1456 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1457 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001458}
1459
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001460void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1461 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001462 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1463 for(int index = 0;index < nYuvCount; index++){
1464 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1465 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1466
1467 if(!isYUVDoable(ctx, layer)) {
1468 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1469 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1470 mCurrentFrame.fbCount++;
1471 }
1472 } else {
1473 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001474 private_handle_t *hnd = (private_handle_t *)layer->handle;
1475 if(!secureOnly || isSecureBuffer(hnd)) {
1476 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1477 mCurrentFrame.fbCount--;
1478 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001479 }
1480 }
1481 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001482
1483 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001484 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1485 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001486 mCurrentFrame.fbCount);
1487}
1488
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001489hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1490 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001491 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001492
1493 /* Update only the region of FB needed for composition */
1494 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1495 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1496 hwc_layer_1_t* layer = &list->hwLayers[i];
1497 hwc_rect_t dst = layer->displayFrame;
1498 fbRect = getUnion(fbRect, dst);
1499 }
1500 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001501 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001502 return fbRect;
1503}
1504
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001505bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1506 hwc_display_contents_1_t* list) {
1507
1508 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001509 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001510 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1511 return false;
1512 }
1513
1514 //Limitations checks
1515 if(!hwLimitationsCheck(ctx, list)) {
1516 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1517 return false;
1518 }
1519
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001520 //Configure framebuffer first if applicable
1521 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001522 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001523 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1524 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001525 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1526 __FUNCTION__);
1527 return false;
1528 }
1529 }
1530
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001531 mCurrentFrame.map();
1532
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001533 if(!allocLayerPipes(ctx, list)) {
1534 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001535 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001536 }
1537
1538 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001539 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001540 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001541 int mdpIndex = mCurrentFrame.layerToMDP[index];
1542 hwc_layer_1_t* layer = &list->hwLayers[index];
1543
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301544 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1545 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1546 mdpNextZOrder++;
1547 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001548 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1549 cur_pipe->zOrder = mdpNextZOrder++;
1550
radhakrishnac9a67412013-09-25 17:40:42 +05301551 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301552 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301553 if(configure4k2kYuv(ctx, layer,
1554 mCurrentFrame.mdpToLayer[mdpIndex])
1555 != 0 ){
1556 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1557 for layer %d",__FUNCTION__, index);
1558 return false;
1559 }
1560 else{
1561 mdpNextZOrder++;
1562 }
1563 continue;
1564 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1566 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301567 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001568 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001569 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001570 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001571 }
1572
Saurabh Shaha36be922013-12-16 18:18:39 -08001573 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1574 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1575 ,__FUNCTION__, mDpy);
1576 return false;
1577 }
1578
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001579 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001580 return true;
1581}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001582
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001583bool MDPComp::resourceCheck(hwc_context_t* ctx,
1584 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001585 const bool fbUsed = mCurrentFrame.fbCount;
1586 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1587 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1588 return false;
1589 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001590 // Init rotCount to number of rotate sessions used by other displays
1591 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1592 // Count the number of rotator sessions required for current display
1593 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1594 if(!mCurrentFrame.isFBComposed[index]) {
1595 hwc_layer_1_t* layer = &list->hwLayers[index];
1596 private_handle_t *hnd = (private_handle_t *)layer->handle;
1597 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1598 rotCount++;
1599 }
1600 }
1601 }
1602 // if number of layers to rotate exceeds max rotator sessions, bail out.
1603 if(rotCount > RotMgr::MAX_ROT_SESS) {
1604 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1605 __FUNCTION__, mDpy);
1606 return false;
1607 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001608 return true;
1609}
1610
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301611bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1612 hwc_display_contents_1_t* list) {
1613
1614 //A-family hw limitation:
1615 //If a layer need alpha scaling, MDP can not support.
1616 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1617 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1618 if(!mCurrentFrame.isFBComposed[i] &&
1619 isAlphaScaled( &list->hwLayers[i])) {
1620 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1621 return false;
1622 }
1623 }
1624 }
1625
1626 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1627 //If multiple layers requires downscaling and also they are overlapping
1628 //fall back to GPU since MDSS can not handle it.
1629 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1630 qdutils::MDPVersion::getInstance().is8x26()) {
1631 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1632 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1633 if(!mCurrentFrame.isFBComposed[i] &&
1634 isDownscaleRequired(botLayer)) {
1635 //if layer-i is marked for MDP and needs downscaling
1636 //check if any MDP layer on top of i & overlaps with layer-i
1637 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1638 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1639 if(!mCurrentFrame.isFBComposed[j] &&
1640 isDownscaleRequired(topLayer)) {
1641 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1642 topLayer->displayFrame);
1643 if(isValidRect(r))
1644 return false;
1645 }
1646 }
1647 }
1648 }
1649 }
1650 return true;
1651}
1652
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001653int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001654 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001655 char property[PROPERTY_VALUE_MAX];
1656
Raj Kamal4393eaa2014-06-06 13:45:20 +05301657 if(!ctx || !list) {
1658 ALOGE("%s: Invalid context or list",__FUNCTION__);
1659 mCachedFrame.reset();
1660 return -1;
1661 }
1662
1663 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1664
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001665 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1666 int currentFlags = atoi(property);
1667 if(currentFlags != sSimulationFlags) {
1668 sSimulationFlags = currentFlags;
1669 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1670 sSimulationFlags, sSimulationFlags);
1671 }
1672 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001673 // reset PTOR
1674 if(!mDpy)
1675 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001676
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301677 //Do not cache the information for next draw cycle.
1678 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1679 ALOGI("%s: Unsupported layer count for mdp composition",
1680 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001681 mCachedFrame.reset();
1682 return -1;
1683 }
1684
Saurabh Shahb39f8152013-08-22 10:21:44 -07001685 //reset old data
1686 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001687 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1688 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301689
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001690 // Detect the start of animation and fall back to GPU only once to cache
1691 // all the layers in FB and display FB content untill animation completes.
1692 if(ctx->listStats[mDpy].isDisplayAnimating) {
1693 mCurrentFrame.needsRedraw = false;
1694 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1695 mCurrentFrame.needsRedraw = true;
1696 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1697 }
1698 setMDPCompLayerFlags(ctx, list);
1699 mCachedFrame.updateCounts(mCurrentFrame);
1700 ret = -1;
1701 return ret;
1702 } else {
1703 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1704 }
1705
Saurabh Shahb39f8152013-08-22 10:21:44 -07001706 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001707 if(isFrameDoable(ctx)) {
1708 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001709
Raj Kamal4393eaa2014-06-06 13:45:20 +05301710 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1711 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001712 setMDPCompLayerFlags(ctx, list);
1713 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001714 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001715 reset(ctx);
1716 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1717 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001718 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001719 }
1720 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001721 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1722 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001723 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001724 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001725
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001726 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001727 ALOGD("GEOMETRY change: %d",
1728 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001729 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001730 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001731 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001732 }
1733
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001734 mCachedFrame.cacheAll(list);
1735 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001736 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001737}
1738
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001739bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301740
1741 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301742 int mdpIndex = mCurrentFrame.layerToMDP[index];
1743 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1744 info.pipeInfo = new MdpYUVPipeInfo;
1745 info.rot = NULL;
1746 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301747
1748 pipe_info.lIndex = ovutils::OV_INVALID;
1749 pipe_info.rIndex = ovutils::OV_INVALID;
1750
Saurabh Shahc62f3982014-03-05 14:28:26 -08001751 Overlay::PipeSpecs pipeSpecs;
1752 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1753 pipeSpecs.needsScaling = true;
1754 pipeSpecs.dpy = mDpy;
1755 pipeSpecs.fb = false;
1756
1757 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301758 if(pipe_info.lIndex == ovutils::OV_INVALID){
1759 bRet = false;
1760 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1761 __FUNCTION__);
1762 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001763 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301764 if(pipe_info.rIndex == ovutils::OV_INVALID){
1765 bRet = false;
1766 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1767 __FUNCTION__);
1768 }
1769 return bRet;
1770}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001771
1772int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1773 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001774 if (ctx->mPtorInfo.isActive()) {
1775 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001776 if (fd < 0) {
1777 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001778 }
1779 }
1780 return fd;
1781}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001782//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001783
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001784void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301785 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001786 //If 4k2k Yuv layer split is possible, and if
1787 //fbz is above 4k2k layer, increment fb zorder by 1
1788 //as we split 4k2k layer and increment zorder for right half
1789 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001790 if(!ctx)
1791 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001792 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301793 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1794 index++) {
1795 if(!mCurrentFrame.isFBComposed[index]) {
1796 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1797 mdpNextZOrder++;
1798 }
1799 mdpNextZOrder++;
1800 hwc_layer_1_t* layer = &list->hwLayers[index];
1801 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301802 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301803 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1804 mCurrentFrame.fbZ += 1;
1805 mdpNextZOrder++;
1806 //As we split 4kx2k yuv layer and program to 2 VG pipes
1807 //(if available) increase mdpcount by 1.
1808 mCurrentFrame.mdpCount++;
1809 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001810 }
1811 }
1812 }
radhakrishnac9a67412013-09-25 17:40:42 +05301813}
1814
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001815/*
1816 * Configures pipe(s) for MDP composition
1817 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001818int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001819 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001820 MdpPipeInfoNonSplit& mdp_info =
1821 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001822 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1823 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1824 eIsFg isFg = IS_FG_OFF;
1825 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001826
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001827 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1828 __FUNCTION__, layer, zOrder, dest);
1829
Saurabh Shah88e4d272013-09-03 13:31:29 -07001830 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001831 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001832}
1833
Saurabh Shah88e4d272013-09-03 13:31:29 -07001834bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001835 hwc_display_contents_1_t* list) {
1836 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001837
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001838 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001839
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001840 hwc_layer_1_t* layer = &list->hwLayers[index];
1841 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301842 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001843 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301844 continue;
1845 }
1846 }
1847
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001848 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001849 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001850 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001851 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001852 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001853
Saurabh Shahc62f3982014-03-05 14:28:26 -08001854 Overlay::PipeSpecs pipeSpecs;
1855 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1856 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1857 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1858 (qdutils::MDPVersion::getInstance().is8x26() and
1859 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1860 pipeSpecs.dpy = mDpy;
1861 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001862 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001863
Saurabh Shahc62f3982014-03-05 14:28:26 -08001864 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1865
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001866 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001867 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001868 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001869 }
1870 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001871 return true;
1872}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001873
radhakrishnac9a67412013-09-25 17:40:42 +05301874int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1875 PipeLayerPair& PipeLayerPair) {
1876 MdpYUVPipeInfo& mdp_info =
1877 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1878 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1879 eIsFg isFg = IS_FG_OFF;
1880 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1881 eDest lDest = mdp_info.lIndex;
1882 eDest rDest = mdp_info.rIndex;
1883
1884 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1885 lDest, rDest, &PipeLayerPair.rot);
1886}
1887
Saurabh Shah88e4d272013-09-03 13:31:29 -07001888bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001889
Raj Kamal4393eaa2014-06-06 13:45:20 +05301890 if(!isEnabled() or !mModeOn) {
1891 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301892 return true;
1893 }
1894
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001895 // Set the Handle timeout to true for MDP or MIXED composition.
1896 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1897 sHandleTimeout = true;
1898 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001899
1900 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001901 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001902
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001903 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1904 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001905 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001906 if(mCurrentFrame.isFBComposed[i]) continue;
1907
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001908 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001909 private_handle_t *hnd = (private_handle_t *)layer->handle;
1910 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001911 if (!(layer->flags & HWC_COLOR_FILL)) {
1912 ALOGE("%s handle null", __FUNCTION__);
1913 return false;
1914 }
1915 // No PLAY for Color layer
1916 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1917 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001918 }
1919
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001920 int mdpIndex = mCurrentFrame.layerToMDP[i];
1921
Raj Kamal389d6e32014-08-04 14:43:24 +05301922 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05301923 {
1924 MdpYUVPipeInfo& pipe_info =
1925 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1926 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1927 ovutils::eDest indexL = pipe_info.lIndex;
1928 ovutils::eDest indexR = pipe_info.rIndex;
1929 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301930 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301931 if(rot) {
1932 rot->queueBuffer(fd, offset);
1933 fd = rot->getDstMemId();
1934 offset = rot->getDstOffset();
1935 }
1936 if(indexL != ovutils::OV_INVALID) {
1937 ovutils::eDest destL = (ovutils::eDest)indexL;
1938 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1939 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1940 if (!ov.queueBuffer(fd, offset, destL)) {
1941 ALOGE("%s: queueBuffer failed for display:%d",
1942 __FUNCTION__, mDpy);
1943 return false;
1944 }
1945 }
1946
1947 if(indexR != ovutils::OV_INVALID) {
1948 ovutils::eDest destR = (ovutils::eDest)indexR;
1949 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1950 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1951 if (!ov.queueBuffer(fd, offset, destR)) {
1952 ALOGE("%s: queueBuffer failed for display:%d",
1953 __FUNCTION__, mDpy);
1954 return false;
1955 }
1956 }
1957 }
1958 else{
1959 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001960 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301961 ovutils::eDest dest = pipe_info.index;
1962 if(dest == ovutils::OV_INVALID) {
1963 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001964 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301965 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001966
radhakrishnac9a67412013-09-25 17:40:42 +05301967 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1968 continue;
1969 }
1970
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001971 int fd = hnd->fd;
1972 uint32_t offset = (uint32_t)hnd->offset;
1973 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1974 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001975 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001976 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001977 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001978 }
1979
radhakrishnac9a67412013-09-25 17:40:42 +05301980 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1981 using pipe: %d", __FUNCTION__, layer,
1982 hnd, dest );
1983
radhakrishnac9a67412013-09-25 17:40:42 +05301984 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1985 if(rot) {
1986 if(!rot->queueBuffer(fd, offset))
1987 return false;
1988 fd = rot->getDstMemId();
1989 offset = rot->getDstOffset();
1990 }
1991
1992 if (!ov.queueBuffer(fd, offset, dest)) {
1993 ALOGE("%s: queueBuffer failed for display:%d ",
1994 __FUNCTION__, mDpy);
1995 return false;
1996 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001997 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001998
1999 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002000 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002001 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002002}
2003
Saurabh Shah88e4d272013-09-03 13:31:29 -07002004//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002005
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002006void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302007 hwc_display_contents_1_t* list){
2008 //if 4kx2k yuv layer is totally present in either in left half
2009 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302010 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302011 if(mCurrentFrame.fbZ >= 0) {
2012 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2013 index++) {
2014 if(!mCurrentFrame.isFBComposed[index]) {
2015 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2016 mdpNextZOrder++;
2017 }
2018 mdpNextZOrder++;
2019 hwc_layer_1_t* layer = &list->hwLayers[index];
2020 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302021 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302022 hwc_rect_t dst = layer->displayFrame;
2023 if((dst.left > lSplit) || (dst.right < lSplit)) {
2024 mCurrentFrame.mdpCount += 1;
2025 }
2026 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2027 mCurrentFrame.fbZ += 1;
2028 mdpNextZOrder++;
2029 }
2030 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002031 }
radhakrishnac9a67412013-09-25 17:40:42 +05302032 }
2033}
2034
Saurabh Shah88e4d272013-09-03 13:31:29 -07002035bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002036 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002037
Saurabh Shahc62f3982014-03-05 14:28:26 -08002038 const int lSplit = getLeftSplit(ctx, mDpy);
2039 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002040 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002041 pipe_info.lIndex = ovutils::OV_INVALID;
2042 pipe_info.rIndex = ovutils::OV_INVALID;
2043
Saurabh Shahc62f3982014-03-05 14:28:26 -08002044 Overlay::PipeSpecs pipeSpecs;
2045 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2046 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2047 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2048 pipeSpecs.dpy = mDpy;
2049 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2050 pipeSpecs.fb = false;
2051
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002052 // Acquire pipe only for the updating half
2053 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2054 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2055
2056 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002057 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002058 if(pipe_info.lIndex == ovutils::OV_INVALID)
2059 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002060 }
2061
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002062 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002063 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2064 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002065 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002066 return false;
2067 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002068
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002069 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002070}
2071
Saurabh Shah88e4d272013-09-03 13:31:29 -07002072bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002073 hwc_display_contents_1_t* list) {
2074 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002075
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002076 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002077
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002078 hwc_layer_1_t* layer = &list->hwLayers[index];
2079 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302080 hwc_rect_t dst = layer->displayFrame;
2081 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302082 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302083 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002084 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302085 continue;
2086 }
2087 }
2088 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002089 int mdpIndex = mCurrentFrame.layerToMDP[index];
2090 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002091 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002092 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002093 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002094
Saurabh Shahc62f3982014-03-05 14:28:26 -08002095 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2096 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2097 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002098 return false;
2099 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002100 }
2101 return true;
2102}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002103
radhakrishnac9a67412013-09-25 17:40:42 +05302104int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2105 PipeLayerPair& PipeLayerPair) {
2106 const int lSplit = getLeftSplit(ctx, mDpy);
2107 hwc_rect_t dst = layer->displayFrame;
2108 if((dst.left > lSplit)||(dst.right < lSplit)){
2109 MdpYUVPipeInfo& mdp_info =
2110 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2111 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2112 eIsFg isFg = IS_FG_OFF;
2113 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2114 eDest lDest = mdp_info.lIndex;
2115 eDest rDest = mdp_info.rIndex;
2116
2117 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2118 lDest, rDest, &PipeLayerPair.rot);
2119 }
2120 else{
2121 return configure(ctx, layer, PipeLayerPair);
2122 }
2123}
2124
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002125/*
2126 * Configures pipe(s) for MDP composition
2127 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002128int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002129 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002130 MdpPipeInfoSplit& mdp_info =
2131 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002132 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2133 eIsFg isFg = IS_FG_OFF;
2134 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2135 eDest lDest = mdp_info.lIndex;
2136 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002137
2138 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2139 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2140
Saurabh Shah88e4d272013-09-03 13:31:29 -07002141 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002142 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002143}
2144
Saurabh Shah88e4d272013-09-03 13:31:29 -07002145bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002146
Raj Kamal4393eaa2014-06-06 13:45:20 +05302147 if(!isEnabled() or !mModeOn) {
2148 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302149 return true;
2150 }
2151
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002152 // Set the Handle timeout to true for MDP or MIXED composition.
2153 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2154 sHandleTimeout = true;
2155 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002156
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002157 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002158 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002159
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002160 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2161 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002162 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002163 if(mCurrentFrame.isFBComposed[i]) continue;
2164
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002165 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002166 private_handle_t *hnd = (private_handle_t *)layer->handle;
2167 if(!hnd) {
2168 ALOGE("%s handle null", __FUNCTION__);
2169 return false;
2170 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002171
2172 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2173 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002174 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002175
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002176 int mdpIndex = mCurrentFrame.layerToMDP[i];
2177
Raj Kamal389d6e32014-08-04 14:43:24 +05302178 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302179 {
2180 MdpYUVPipeInfo& pipe_info =
2181 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2182 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2183 ovutils::eDest indexL = pipe_info.lIndex;
2184 ovutils::eDest indexR = pipe_info.rIndex;
2185 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302186 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302187 if(rot) {
2188 rot->queueBuffer(fd, offset);
2189 fd = rot->getDstMemId();
2190 offset = rot->getDstOffset();
2191 }
2192 if(indexL != ovutils::OV_INVALID) {
2193 ovutils::eDest destL = (ovutils::eDest)indexL;
2194 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2195 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2196 if (!ov.queueBuffer(fd, offset, destL)) {
2197 ALOGE("%s: queueBuffer failed for display:%d",
2198 __FUNCTION__, mDpy);
2199 return false;
2200 }
2201 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002202
radhakrishnac9a67412013-09-25 17:40:42 +05302203 if(indexR != ovutils::OV_INVALID) {
2204 ovutils::eDest destR = (ovutils::eDest)indexR;
2205 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2206 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2207 if (!ov.queueBuffer(fd, offset, destR)) {
2208 ALOGE("%s: queueBuffer failed for display:%d",
2209 __FUNCTION__, mDpy);
2210 return false;
2211 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002212 }
2213 }
radhakrishnac9a67412013-09-25 17:40:42 +05302214 else{
2215 MdpPipeInfoSplit& pipe_info =
2216 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2217 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002218
radhakrishnac9a67412013-09-25 17:40:42 +05302219 ovutils::eDest indexL = pipe_info.lIndex;
2220 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002221
radhakrishnac9a67412013-09-25 17:40:42 +05302222 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002223 uint32_t offset = (uint32_t)hnd->offset;
2224 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2225 if (!mDpy && (index != -1)) {
2226 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2227 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002228 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002229 }
radhakrishnac9a67412013-09-25 17:40:42 +05302230
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002231 if(ctx->mAD->draw(ctx, fd, offset)) {
2232 fd = ctx->mAD->getDstFd();
2233 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002234 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002235
radhakrishnac9a67412013-09-25 17:40:42 +05302236 if(rot) {
2237 rot->queueBuffer(fd, offset);
2238 fd = rot->getDstMemId();
2239 offset = rot->getDstOffset();
2240 }
2241
2242 //************* play left mixer **********
2243 if(indexL != ovutils::OV_INVALID) {
2244 ovutils::eDest destL = (ovutils::eDest)indexL;
2245 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2246 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2247 if (!ov.queueBuffer(fd, offset, destL)) {
2248 ALOGE("%s: queueBuffer failed for left mixer",
2249 __FUNCTION__);
2250 return false;
2251 }
2252 }
2253
2254 //************* play right mixer **********
2255 if(indexR != ovutils::OV_INVALID) {
2256 ovutils::eDest destR = (ovutils::eDest)indexR;
2257 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2258 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2259 if (!ov.queueBuffer(fd, offset, destR)) {
2260 ALOGE("%s: queueBuffer failed for right mixer",
2261 __FUNCTION__);
2262 return false;
2263 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002264 }
2265 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002266
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002267 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2268 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002269
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002270 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002271}
Saurabh Shahab47c692014-02-12 18:45:57 -08002272
2273//================MDPCompSrcSplit==============================================
2274bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002275 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002276 private_handle_t *hnd = (private_handle_t *)layer->handle;
2277 hwc_rect_t dst = layer->displayFrame;
2278 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2279 pipe_info.lIndex = ovutils::OV_INVALID;
2280 pipe_info.rIndex = ovutils::OV_INVALID;
2281
2282 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2283 //should have a higher priority than the right one. Pipe priorities are
2284 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002285
Saurabh Shahc62f3982014-03-05 14:28:26 -08002286 Overlay::PipeSpecs pipeSpecs;
2287 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2288 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2289 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2290 pipeSpecs.dpy = mDpy;
2291 pipeSpecs.fb = false;
2292
Saurabh Shahab47c692014-02-12 18:45:57 -08002293 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002294 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002295 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002296 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002297 }
2298
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002299 /* Use 2 pipes IF
2300 a) Layer's crop width is > 2048 or
2301 b) Layer's dest width > 2048 or
2302 c) On primary, driver has indicated with caps to split always. This is
2303 based on an empirically derived value of panel height. Applied only
2304 if the layer's width is > mixer's width
2305 */
2306
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302307 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002308 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302309 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002310 int lSplit = getLeftSplit(ctx, mDpy);
2311 int dstWidth = dst.right - dst.left;
2312 int cropWidth = crop.right - crop.left;
2313
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302314 if(dstWidth > mdpHw.getMaxMixerWidth() or
2315 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002316 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002317 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002318 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002319 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002320 }
2321
2322 // Return values
2323 // 1 Left pipe is higher priority, do nothing.
2324 // 0 Pipes of same priority.
2325 //-1 Right pipe is of higher priority, needs swap.
2326 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2327 pipe_info.rIndex) == -1) {
2328 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002329 }
2330 }
2331
2332 return true;
2333}
2334
Saurabh Shahab47c692014-02-12 18:45:57 -08002335int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2336 PipeLayerPair& PipeLayerPair) {
2337 private_handle_t *hnd = (private_handle_t *)layer->handle;
2338 if(!hnd) {
2339 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2340 return -1;
2341 }
2342 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2343 MdpPipeInfoSplit& mdp_info =
2344 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2345 Rotator **rot = &PipeLayerPair.rot;
2346 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2347 eIsFg isFg = IS_FG_OFF;
2348 eDest lDest = mdp_info.lIndex;
2349 eDest rDest = mdp_info.rIndex;
2350 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2351 hwc_rect_t dst = layer->displayFrame;
2352 int transform = layer->transform;
2353 eTransform orient = static_cast<eTransform>(transform);
2354 const int downscale = 0;
2355 int rotFlags = ROT_FLAGS_NONE;
2356 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2357 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2358
2359 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2360 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2361
2362 // Handle R/B swap
2363 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2364 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2365 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2366 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2367 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2368 }
2369
Saurabh Shah97e2d802014-04-14 18:03:54 -07002370 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002371 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002372
2373 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2374 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002375 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002376 }
2377
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002378 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002379 (*rot) = ctx->mRotMgr->getNext();
2380 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002381 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002382 //If the video is using a single pipe, enable BWC
2383 if(rDest == OV_INVALID) {
2384 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2385 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002386 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002387 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002388 ALOGE("%s: configRotator failed!", __FUNCTION__);
2389 return -1;
2390 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002391 updateSource(orient, whf, crop, *rot);
Saurabh Shahab47c692014-02-12 18:45:57 -08002392 rotFlags |= ROT_PREROTATED;
2393 }
2394
2395 //If 2 pipes being used, divide layer into half, crop and dst
2396 hwc_rect_t cropL = crop;
2397 hwc_rect_t cropR = crop;
2398 hwc_rect_t dstL = dst;
2399 hwc_rect_t dstR = dst;
2400 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2401 cropL.right = (crop.right + crop.left) / 2;
2402 cropR.left = cropL.right;
2403 sanitizeSourceCrop(cropL, cropR, hnd);
2404
2405 //Swap crops on H flip since 2 pipes are being used
2406 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2407 hwc_rect_t tmp = cropL;
2408 cropL = cropR;
2409 cropR = tmp;
2410 }
2411
2412 dstL.right = (dst.right + dst.left) / 2;
2413 dstR.left = dstL.right;
2414 }
2415
2416 //For the mdp, since either we are pre-rotating or MDP does flips
2417 orient = OVERLAY_TRANSFORM_0;
2418 transform = 0;
2419
2420 //configure left pipe
2421 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002422 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002423 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2424 (ovutils::eBlending) getBlending(layer->blending));
2425
2426 if(configMdp(ctx->mOverlay, pargL, orient,
2427 cropL, dstL, metadata, lDest) < 0) {
2428 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2429 return -1;
2430 }
2431 }
2432
2433 //configure right pipe
2434 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002435 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002436 static_cast<eRotFlags>(rotFlags),
2437 layer->planeAlpha,
2438 (ovutils::eBlending) getBlending(layer->blending));
2439 if(configMdp(ctx->mOverlay, pargR, orient,
2440 cropR, dstR, metadata, rDest) < 0) {
2441 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2442 return -1;
2443 }
2444 }
2445
2446 return 0;
2447}
2448
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002449}; //namespace
2450