blob: 3a60fa3b03a8c9237ea13eed2fe5a876b8c982c7 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
radhakrishnac9a67412013-09-25 17:40:42 +053048bool MDPComp::sEnable4k2kYUVSplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
138 // Idle invalidation is not necessary on command mode panels
139 long idle_timeout = DEFAULT_IDLE_TIME;
140 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
141 if(atoi(property) != 0)
142 idle_timeout = atoi(property);
143 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800144
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400145 //create Idle Invalidator only when not disabled through property
146 if(idle_timeout != -1)
147 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800148
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400149 if(idleInvalidator == NULL) {
150 ALOGE("%s: failed to instantiate idleInvalidator object",
151 __FUNCTION__);
152 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530153 idleInvalidator->init(timeout_handler, ctx,
154 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400155 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800156 }
radhakrishnac9a67412013-09-25 17:40:42 +0530157
Saurabh Shah7c727642014-06-02 15:47:14 -0700158 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
159 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
160 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
161 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
radhakrishnac9a67412013-09-25 17:40:42 +0530162 sEnable4k2kYUVSplit = true;
163 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164
165 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
166 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
167 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
169 HWC_DISPLAY_PRIMARY);
170 }
171
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700172 return true;
173}
174
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800175void MDPComp::reset(hwc_context_t *ctx) {
176 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700177 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800178 ctx->mOverlay->clear(mDpy);
179 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700180}
181
Raj Kamal4393eaa2014-06-06 13:45:20 +0530182void MDPComp::reset() {
183 sHandleTimeout = false;
184 mModeOn = false;
185}
186
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700187void MDPComp::timeout_handler(void *udata) {
188 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
189
190 if(!ctx) {
191 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
192 return;
193 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800194 Locker::Autolock _l(ctx->mDrawLock);
195 // Handle timeout event only if the previous composition is MDP or MIXED.
196 if(!sHandleTimeout) {
197 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
198 return;
199 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700200 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700201 ALOGE("%s: HWC proc not registered", __FUNCTION__);
202 return;
203 }
204 sIdleFallBack = true;
205 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700206 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700207}
208
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800209void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800210 hwc_display_contents_1_t* list) {
211 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800212
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800213 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 if(!mCurrentFrame.isFBComposed[index]) {
216 layerProp[index].mFlags |= HWC_MDPCOMP;
217 layer->compositionType = HWC_OVERLAY;
218 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700220 /* Drop the layer when its already present in FB OR when it lies
221 * outside frame's ROI */
222 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700224 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800225 }
226 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500228
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800229void MDPComp::setRedraw(hwc_context_t *ctx,
230 hwc_display_contents_1_t* list) {
231 mCurrentFrame.needsRedraw = false;
232 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
233 (list->flags & HWC_GEOMETRY_CHANGED) ||
234 isSkipPresent(ctx, mDpy)) {
235 mCurrentFrame.needsRedraw = true;
236 }
237}
238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700240 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800242
Saurabh Shahaa236822013-04-24 18:07:26 -0700243void MDPComp::FrameInfo::reset(const int& numLayers) {
244 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245 if(mdpToLayer[i].pipeInfo) {
246 delete mdpToLayer[i].pipeInfo;
247 mdpToLayer[i].pipeInfo = NULL;
248 //We dont own the rotator
249 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800250 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800251 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800252
253 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
254 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700255 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800256
Saurabh Shahaa236822013-04-24 18:07:26 -0700257 layerCount = numLayers;
258 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800259 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700260 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800261 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800262}
263
Saurabh Shahaa236822013-04-24 18:07:26 -0700264void MDPComp::FrameInfo::map() {
265 // populate layer and MDP maps
266 int mdpIdx = 0;
267 for(int idx = 0; idx < layerCount; idx++) {
268 if(!isFBComposed[idx]) {
269 mdpToLayer[mdpIdx].listIndex = idx;
270 layerToMDP[idx] = mdpIdx++;
271 }
272 }
273}
274
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800275MDPComp::LayerCache::LayerCache() {
276 reset();
277}
278
279void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700280 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530281 memset(&isFBComposed, true, sizeof(isFBComposed));
282 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700284}
285
286void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530287 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700288 for(int i = 0; i < numAppLayers; i++) {
289 hnd[i] = list->hwLayers[i].handle;
290 }
291}
292
293void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700294 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530295 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
296 memcpy(&drop, &curFrame.drop, sizeof(drop));
297}
298
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800299bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
300 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530301 if(layerCount != curFrame.layerCount)
302 return false;
303 for(int i = 0; i < curFrame.layerCount; i++) {
304 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
305 (curFrame.drop[i] != drop[i])) {
306 return false;
307 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800308 if(curFrame.isFBComposed[i] &&
309 (hnd[i] != list->hwLayers[i].handle)){
310 return false;
311 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530312 }
313 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800314}
315
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700316bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
317 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800318 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700319 (not isValidDimension(ctx,layer))
320 //More conditions here, SKIP, sRGB+Blend etc
321 ) {
322 return false;
323 }
324 return true;
325}
326
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530327bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800328 private_handle_t *hnd = (private_handle_t *)layer->handle;
329
330 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700331 if (layer->flags & HWC_COLOR_FILL) {
332 // Color layer
333 return true;
334 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800335 ALOGE("%s: layer handle is NULL", __FUNCTION__);
336 return false;
337 }
338
Naseer Ahmede850a802013-09-06 13:12:52 -0400339 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400340 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400341 return false;
342
Saurabh Shah62e1d732013-09-17 10:44:05 -0700343 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700344 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700345 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700346 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
347 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700348 int dst_w = dst.right - dst.left;
349 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800350 float w_scale = ((float)crop_w / (float)dst_w);
351 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700352
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800353 /* Workaround for MDP HW limitation in DSI command mode panels where
354 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
355 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530356 * There also is a HW limilation in MDP, minimum block size is 2x2
357 * Fallback to GPU if height is less than 2.
358 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800359 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800360 return false;
361
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800362 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700363 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700364 qdutils::MDPVersion::getInstance().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
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800370 if(!qdutils::MDPVersion::getInstance().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 */
374 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
375 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800376 return false;
377 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700378 // Decimation on macrotile format layers is not supported.
379 if(isTileRendered(hnd)) {
380 /* MDP can read maximum MAX_DISPLAY_DIM width.
381 * Bail out if
382 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
383 * 2. exceeds maximum downscale limit
384 */
385 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
386 w_dscale > maxMDPDownscale ||
387 h_dscale > maxMDPDownscale) {
388 return false;
389 }
390 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800391 return false;
392 }
393 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700394 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700395 return false;
396 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 }
398
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800399 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
400 const uint32_t upscale =
401 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
402 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
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800691 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
692 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
693 // Disable MDP comp on Secondary when the primary is highres panel and
694 // the secondary is a normal 1080p, because, MDP comp on secondary under
695 // in such usecase, decimation gets used for downscale and there will be
696 // a quality mismatch when there will be a fallback to GPU comp
697 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
698 __FUNCTION__);
699 return false;
700 }
701
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800702 // check for action safe flag and downscale mode which requires scaling.
703 if(ctx->dpyAttr[mDpy].mActionSafePresent
704 || ctx->dpyAttr[mDpy].mDownScaleMode) {
705 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
706 return false;
707 }
708
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800709 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800710 hwc_layer_1_t* layer = &list->hwLayers[i];
711 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800712
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800713 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700714 if(!canUseRotator(ctx, mDpy)) {
715 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
716 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700717 return false;
718 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800719 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530720
721 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
722 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700723 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530724 if(qdutils::MDPVersion::getInstance().is8x26() &&
725 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700726 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530727 (!isYuvBuffer(hnd)))
728 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800729 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700730
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700731 if(ctx->mAD->isDoable()) {
732 return false;
733 }
734
Saurabh Shahaa236822013-04-24 18:07:26 -0700735 //If all above hard conditions are met we can do full or partial MDP comp.
736 bool ret = false;
737 if(fullMDPComp(ctx, list)) {
738 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700739 } else if(fullMDPCompWithPTOR(ctx, list)) {
740 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700741 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700742 ret = true;
743 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530744
Saurabh Shahaa236822013-04-24 18:07:26 -0700745 return ret;
746}
747
748bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700749
750 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
751 return false;
752
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700753 //Will benefit presentation / secondary-only layer.
754 if((mDpy > HWC_DISPLAY_PRIMARY) &&
755 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
756 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
757 return false;
758 }
759
760 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
761 for(int i = 0; i < numAppLayers; i++) {
762 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700763 if(not mCurrentFrame.drop[i] and
764 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700765 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
766 return false;
767 }
768 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800769
Saurabh Shahaa236822013-04-24 18:07:26 -0700770 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700771 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
772 sizeof(mCurrentFrame.isFBComposed));
773 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
774 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700775
radhakrishnac9a67412013-09-25 17:40:42 +0530776 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800777 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530778 }
779
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800780 if(!postHeuristicsHandling(ctx, list)) {
781 ALOGD_IF(isDebug(), "post heuristic handling failed");
782 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700783 return false;
784 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700785 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
786 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700787 return true;
788}
789
Sushil Chauhandefd3522014-05-13 18:17:12 -0700790/* Full MDP Composition with Peripheral Tiny Overlap Removal.
791 * MDP bandwidth limitations can be avoided, if the overlap region
792 * covered by the smallest layer at a higher z-order, gets composed
793 * by Copybit on a render buffer, which can be queued to MDP.
794 */
795bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
796 hwc_display_contents_1_t* list) {
797
798 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
799 const int stagesForMDP = min(sMaxPipesPerMixer,
800 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
801
802 // Hard checks where we cannot use this mode
803 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
804 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
805 return false;
806 }
807
808 // Frame level checks
809 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
810 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
811 isSecurePresent(ctx, mDpy)) {
812 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
813 return false;
814 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700815 // MDP comp checks
816 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700817 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700818 if(not isSupportedForMDPComp(ctx, layer)) {
819 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
820 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700821 }
822 }
823
Sushil Chauhandefd3522014-05-13 18:17:12 -0700824 /* We cannot use this composition mode, if:
825 1. A below layer needs scaling.
826 2. Overlap is not peripheral to display.
827 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700828 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700829 */
830
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700831 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
832 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
833 memset(overlapRect, 0, sizeof(overlapRect));
834 int layerPixelCount, minPixelCount = 0;
835 int numPTORLayersFound = 0;
836 for (int i = numAppLayers-1; (i >= 0 &&
837 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700838 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700839 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700841 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
842 // PTOR layer should be peripheral and cannot have transform
843 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
844 has90Transform(layer)) {
845 continue;
846 }
847 if((3 * (layerPixelCount + minPixelCount)) >
848 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
849 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
850 continue;
851 }
852 // Found the PTOR layer
853 bool found = true;
854 for (int j = i-1; j >= 0; j--) {
855 // Check if the layers below this layer qualifies for PTOR comp
856 hwc_layer_1_t* layer = &list->hwLayers[j];
857 hwc_rect_t disFrame = layer->displayFrame;
858 //layer below PTOR is intersecting and has 90 degree transform or
859 // needs scaling cannot be supported.
860 if ((isValidRect(getIntersection(dispFrame, disFrame)))
861 && (has90Transform(layer) || needsScaling(layer))) {
862 found = false;
863 break;
864 }
865 }
866 // Store the minLayer Index
867 if(found) {
868 minLayerIndex[numPTORLayersFound] = i;
869 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
870 minPixelCount += layerPixelCount;
871 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700872 }
873 }
874
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700875 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
876 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
877 __FUNCTION__);
878 // reset second minLayerIndex[1];
879 minLayerIndex[1] = -1;
880 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700881 }
882
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700883 // No overlap layers
884 if (!numPTORLayersFound)
885 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700887 ctx->mPtorInfo.count = numPTORLayersFound;
888 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
889 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
890 }
891
892 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
893 // reset PTOR
894 ctx->mPtorInfo.count = 0;
895 return false;
896 }
897 // Store the displayFrame and the sourceCrops of the layers
898 hwc_rect_t displayFrame[numAppLayers];
899 hwc_rect_t sourceCrop[numAppLayers];
900 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700901 hwc_layer_1_t* layer = &list->hwLayers[i];
902 displayFrame[i] = layer->displayFrame;
903 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700904 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700905
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 for(int j = 0; j < numPTORLayersFound; j++) {
907 int index = ctx->mPtorInfo.layerIndex[j];
908 // Remove overlap from crop & displayFrame of below layers
909 for (int i = 0; i < index && index !=-1; i++) {
910 hwc_layer_1_t* layer = &list->hwLayers[i];
911 if(!isValidRect(getIntersection(layer->displayFrame,
912 overlapRect[j]))) {
913 continue;
914 }
915 // Update layer attributes
916 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
917 hwc_rect_t destRect = deductRect(layer->displayFrame,
918 overlapRect[j]);
919 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
920 layer->transform);
921 layer->sourceCropf.left = (float)srcCrop.left;
922 layer->sourceCropf.top = (float)srcCrop.top;
923 layer->sourceCropf.right = (float)srcCrop.right;
924 layer->sourceCropf.bottom = (float)srcCrop.bottom;
925 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700926 }
927
928 mCurrentFrame.mdpCount = numAppLayers;
929 mCurrentFrame.fbCount = 0;
930 mCurrentFrame.fbZ = -1;
931
932 for (int j = 0; j < numAppLayers; j++)
933 mCurrentFrame.isFBComposed[j] = false;
934
935 bool result = postHeuristicsHandling(ctx, list);
936
937 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700939 hwc_layer_1_t* layer = &list->hwLayers[i];
940 layer->displayFrame = displayFrame[i];
941 layer->sourceCropf.left = (float)sourceCrop[i].left;
942 layer->sourceCropf.top = (float)sourceCrop[i].top;
943 layer->sourceCropf.right = (float)sourceCrop[i].right;
944 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
945 }
946
947 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700948 // reset PTOR
949 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700950 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 } else {
952 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
953 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700954 }
955
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
957 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -0700958 return result;
959}
960
Saurabh Shahaa236822013-04-24 18:07:26 -0700961bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
962{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700963 if(!sEnableMixedMode) {
964 //Mixed mode is disabled. No need to even try caching.
965 return false;
966 }
967
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700968 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800969 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800970 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800971 cacheBasedComp(ctx, list);
972 } else {
973 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800974 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700975 }
976
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700977 return ret;
978}
979
980bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
981 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700982 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
983 return false;
984
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700985 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700986 mCurrentFrame.reset(numAppLayers);
987 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700988
989 //If an MDP marked layer is unsupported cannot do partial MDP Comp
990 for(int i = 0; i < numAppLayers; i++) {
991 if(!mCurrentFrame.isFBComposed[i]) {
992 hwc_layer_1_t* layer = &list->hwLayers[i];
993 if(not isSupportedForMDPComp(ctx, layer)) {
994 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
995 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800996 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700997 return false;
998 }
999 }
1000 }
1001
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001002 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301003 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001004 if(!ret) {
1005 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001006 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001007 return false;
1008 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001009
1010 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001011
radhakrishnac9a67412013-09-25 17:40:42 +05301012 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001013 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301014 }
1015
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001016 //Will benefit cases where a video has non-updating background.
1017 if((mDpy > HWC_DISPLAY_PRIMARY) and
1018 (mdpCount > MAX_SEC_LAYERS)) {
1019 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001020 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001021 return false;
1022 }
1023
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001024 if(!postHeuristicsHandling(ctx, list)) {
1025 ALOGD_IF(isDebug(), "post heuristic handling failed");
1026 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001027 return false;
1028 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001029 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1030 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001031
Saurabh Shahaa236822013-04-24 18:07:26 -07001032 return true;
1033}
1034
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001035bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001036 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001037 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1038 return false;
1039
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001040 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001041 return false;
1042 }
1043
Saurabh Shahb772ae32013-11-18 15:40:02 -08001044 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001045 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1046 const int stagesForMDP = min(sMaxPipesPerMixer,
1047 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001048
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001049 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1050 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1051 int lastMDPSupportedIndex = numAppLayers;
1052 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001053
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001054 //Find the minimum MDP batch size
1055 for(int i = 0; i < numAppLayers;i++) {
1056 if(mCurrentFrame.drop[i]) {
1057 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001058 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001059 }
1060 hwc_layer_1_t* layer = &list->hwLayers[i];
1061 if(not isSupportedForMDPComp(ctx, layer)) {
1062 lastMDPSupportedIndex = i;
1063 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1064 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001065 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001066 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001067 }
1068
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001069 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1070 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1071 mCurrentFrame.dropCount);
1072
1073 //Start at a point where the fb batch should at least have 2 layers, for
1074 //this mode to be justified.
1075 while(fbBatchSize < 2) {
1076 ++fbBatchSize;
1077 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001078 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001079
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001080 //If there are no layers for MDP, this mode doesnt make sense.
1081 if(mdpBatchSize < 1) {
1082 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1083 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001084 return false;
1085 }
1086
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001087 mCurrentFrame.reset(numAppLayers);
1088
1089 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1090 while(mdpBatchSize > 0) {
1091 //Mark layers for MDP comp
1092 int mdpBatchLeft = mdpBatchSize;
1093 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1094 if(mCurrentFrame.drop[i]) {
1095 continue;
1096 }
1097 mCurrentFrame.isFBComposed[i] = false;
1098 --mdpBatchLeft;
1099 }
1100
1101 mCurrentFrame.fbZ = mdpBatchSize;
1102 mCurrentFrame.fbCount = fbBatchSize;
1103 mCurrentFrame.mdpCount = mdpBatchSize;
1104
1105 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1106 __FUNCTION__, mdpBatchSize, fbBatchSize,
1107 mCurrentFrame.dropCount);
1108
1109 if(postHeuristicsHandling(ctx, list)) {
1110 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001111 __FUNCTION__);
1112 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1113 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001114 return true;
1115 }
1116
1117 reset(ctx);
1118 --mdpBatchSize;
1119 ++fbBatchSize;
1120 }
1121
1122 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001123}
1124
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001125bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301126 if(mDpy or isSecurePresent(ctx, mDpy) or
1127 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001128 return false;
1129 }
1130 return true;
1131}
1132
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001133bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1134 hwc_display_contents_1_t* list){
1135 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1136 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1137 mDpy ) {
1138 return false;
1139 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001140 if(ctx->listStats[mDpy].secureUI)
1141 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001142 return true;
1143}
1144
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001145bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1146 hwc_display_contents_1_t* list) {
1147 const bool secureOnly = true;
1148 return videoOnlyComp(ctx, list, not secureOnly) or
1149 videoOnlyComp(ctx, list, secureOnly);
1150}
1151
1152bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001153 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001154 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1155 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001156 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001157
Saurabh Shahaa236822013-04-24 18:07:26 -07001158 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001159 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001160 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001161 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001162
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001163 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1164 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001165 return false;
1166 }
1167
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001168 /* Bail out if we are processing only secured video layers
1169 * and we dont have any */
1170 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001171 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001172 return false;
1173 }
1174
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001175 if(mCurrentFrame.fbCount)
1176 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001177
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001178 if(sEnable4k2kYUVSplit){
1179 adjustForSourceSplit(ctx, list);
1180 }
1181
1182 if(!postHeuristicsHandling(ctx, list)) {
1183 ALOGD_IF(isDebug(), "post heuristic handling failed");
1184 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001185 return false;
1186 }
1187
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001188 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1189 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001190 return true;
1191}
1192
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001193/* Checks for conditions where YUV layers cannot be bypassed */
1194bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001195 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001196 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001197 return false;
1198 }
1199
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001200 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001201 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1202 return false;
1203 }
1204
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001205 if(isSecuring(ctx, layer)) {
1206 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1207 return false;
1208 }
1209
Saurabh Shah4fdde762013-04-30 18:47:33 -07001210 if(!isValidDimension(ctx, layer)) {
1211 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1212 __FUNCTION__);
1213 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001214 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001215
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001216 if(layer->planeAlpha < 0xFF) {
1217 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1218 in video only mode",
1219 __FUNCTION__);
1220 return false;
1221 }
1222
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001223 return true;
1224}
1225
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301226/* starts at fromIndex and check for each layer to find
1227 * if it it has overlapping with any Updating layer above it in zorder
1228 * till the end of the batch. returns true if it finds any intersection */
1229bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1230 int fromIndex, int toIndex) {
1231 for(int i = fromIndex; i < toIndex; i++) {
1232 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1233 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1234 return false;
1235 }
1236 }
1237 }
1238 return true;
1239}
1240
1241/* Checks if given layer at targetLayerIndex has any
1242 * intersection with all the updating layers in beween
1243 * fromIndex and toIndex. Returns true if it finds intersectiion */
1244bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1245 int fromIndex, int toIndex, int targetLayerIndex) {
1246 for(int i = fromIndex; i <= toIndex; i++) {
1247 if(!mCurrentFrame.isFBComposed[i]) {
1248 if(areLayersIntersecting(&list->hwLayers[i],
1249 &list->hwLayers[targetLayerIndex])) {
1250 return true;
1251 }
1252 }
1253 }
1254 return false;
1255}
1256
1257int MDPComp::getBatch(hwc_display_contents_1_t* list,
1258 int& maxBatchStart, int& maxBatchEnd,
1259 int& maxBatchCount) {
1260 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301261 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001262 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301263 while (i < mCurrentFrame.layerCount) {
1264 int batchCount = 0;
1265 int batchStart = i;
1266 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001267 /* Adjust batch Z order with the dropped layers so far */
1268 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301269 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301270 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301271 while(i < mCurrentFrame.layerCount) {
1272 if(!mCurrentFrame.isFBComposed[i]) {
1273 if(!batchCount) {
1274 i++;
1275 break;
1276 }
1277 updatingLayersAbove++;
1278 i++;
1279 continue;
1280 } else {
1281 if(mCurrentFrame.drop[i]) {
1282 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001283 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301284 continue;
1285 } else if(updatingLayersAbove <= 0) {
1286 batchCount++;
1287 batchEnd = i;
1288 i++;
1289 continue;
1290 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1291
1292 // We have a valid updating layer already. If layer-i not
1293 // have overlapping with all updating layers in between
1294 // batch-start and i, then we can add layer i to batch.
1295 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1296 batchCount++;
1297 batchEnd = i;
1298 i++;
1299 continue;
1300 } else if(canPushBatchToTop(list, batchStart, i)) {
1301 //If All the non-updating layers with in this batch
1302 //does not have intersection with the updating layers
1303 //above in z-order, then we can safely move the batch to
1304 //higher z-order. Increment fbZ as it is moving up.
1305 if( firstZReverseIndex < 0) {
1306 firstZReverseIndex = i;
1307 }
1308 batchCount++;
1309 batchEnd = i;
1310 fbZ += updatingLayersAbove;
1311 i++;
1312 updatingLayersAbove = 0;
1313 continue;
1314 } else {
1315 //both failed.start the loop again from here.
1316 if(firstZReverseIndex >= 0) {
1317 i = firstZReverseIndex;
1318 }
1319 break;
1320 }
1321 }
1322 }
1323 }
1324 if(batchCount > maxBatchCount) {
1325 maxBatchCount = batchCount;
1326 maxBatchStart = batchStart;
1327 maxBatchEnd = batchEnd;
1328 fbZOrder = fbZ;
1329 }
1330 }
1331 return fbZOrder;
1332}
1333
1334bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1335 hwc_display_contents_1_t* list) {
1336 /* Idea is to keep as many non-updating(cached) layers in FB and
1337 * send rest of them through MDP. This is done in 2 steps.
1338 * 1. Find the maximum contiguous batch of non-updating layers.
1339 * 2. See if we can improve this batch size for caching by adding
1340 * opaque layers around the batch, if they don't have
1341 * any overlapping with the updating layers in between.
1342 * NEVER mark an updating layer for caching.
1343 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001344
1345 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001346 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001347 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301348 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001349
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001350 /* Nothing is cached. No batching needed */
1351 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001352 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001353 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001354
1355 /* No MDP comp layers, try to use other comp modes */
1356 if(mCurrentFrame.mdpCount == 0) {
1357 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001358 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001359
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301360 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001361
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301362 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001363 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001364 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001365 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301366 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001367 if(!mCurrentFrame.drop[i]){
1368 //If an unsupported layer is being attempted to
1369 //be pulled out we should fail
1370 if(not isSupportedForMDPComp(ctx, layer)) {
1371 return false;
1372 }
1373 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001374 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001375 }
1376 }
1377
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301378 // update the frame data
1379 mCurrentFrame.fbZ = fbZ;
1380 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001381 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001382 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001383
1384 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301385 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001386
1387 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001388}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001389
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001390void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001391 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001392 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001393 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001394
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001395 for(int i = 0; i < numAppLayers; i++) {
1396 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001397 if(!mCurrentFrame.drop[i])
1398 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001399 mCurrentFrame.isFBComposed[i] = true;
1400 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001401 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001402 }
1403 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001404
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001405 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001406 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1407 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001408
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001409 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1410 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1411 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001412}
1413
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001414void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1415 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001416 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1417 for(int index = 0;index < nYuvCount; index++){
1418 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1419 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1420
1421 if(!isYUVDoable(ctx, layer)) {
1422 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1423 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1424 mCurrentFrame.fbCount++;
1425 }
1426 } else {
1427 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001428 private_handle_t *hnd = (private_handle_t *)layer->handle;
1429 if(!secureOnly || isSecureBuffer(hnd)) {
1430 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1431 mCurrentFrame.fbCount--;
1432 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001433 }
1434 }
1435 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001436
1437 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001438 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1439 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001440 mCurrentFrame.fbCount);
1441}
1442
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001443hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1444 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001445 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001446
1447 /* Update only the region of FB needed for composition */
1448 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1449 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1450 hwc_layer_1_t* layer = &list->hwLayers[i];
1451 hwc_rect_t dst = layer->displayFrame;
1452 fbRect = getUnion(fbRect, dst);
1453 }
1454 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001455 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001456 return fbRect;
1457}
1458
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001459bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1460 hwc_display_contents_1_t* list) {
1461
1462 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001463 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001464 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1465 return false;
1466 }
1467
1468 //Limitations checks
1469 if(!hwLimitationsCheck(ctx, list)) {
1470 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1471 return false;
1472 }
1473
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001474 //Configure framebuffer first if applicable
1475 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001476 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001477 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1478 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001479 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1480 __FUNCTION__);
1481 return false;
1482 }
1483 }
1484
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001485 mCurrentFrame.map();
1486
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001487 if(!allocLayerPipes(ctx, list)) {
1488 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001489 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001490 }
1491
1492 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001493 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001494 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001495 int mdpIndex = mCurrentFrame.layerToMDP[index];
1496 hwc_layer_1_t* layer = &list->hwLayers[index];
1497
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301498 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1499 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1500 mdpNextZOrder++;
1501 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001502 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1503 cur_pipe->zOrder = mdpNextZOrder++;
1504
radhakrishnac9a67412013-09-25 17:40:42 +05301505 private_handle_t *hnd = (private_handle_t *)layer->handle;
1506 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1507 if(configure4k2kYuv(ctx, layer,
1508 mCurrentFrame.mdpToLayer[mdpIndex])
1509 != 0 ){
1510 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1511 for layer %d",__FUNCTION__, index);
1512 return false;
1513 }
1514 else{
1515 mdpNextZOrder++;
1516 }
1517 continue;
1518 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001519 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1520 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301521 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001522 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001523 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001524 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001525 }
1526
Saurabh Shaha36be922013-12-16 18:18:39 -08001527 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1528 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1529 ,__FUNCTION__, mDpy);
1530 return false;
1531 }
1532
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001533 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001534 return true;
1535}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001536
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001537bool MDPComp::resourceCheck(hwc_context_t* ctx,
1538 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001539 const bool fbUsed = mCurrentFrame.fbCount;
1540 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1541 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1542 return false;
1543 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001544 // Init rotCount to number of rotate sessions used by other displays
1545 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1546 // Count the number of rotator sessions required for current display
1547 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1548 if(!mCurrentFrame.isFBComposed[index]) {
1549 hwc_layer_1_t* layer = &list->hwLayers[index];
1550 private_handle_t *hnd = (private_handle_t *)layer->handle;
1551 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1552 rotCount++;
1553 }
1554 }
1555 }
1556 // if number of layers to rotate exceeds max rotator sessions, bail out.
1557 if(rotCount > RotMgr::MAX_ROT_SESS) {
1558 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1559 __FUNCTION__, mDpy);
1560 return false;
1561 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001562 return true;
1563}
1564
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301565bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1566 hwc_display_contents_1_t* list) {
1567
1568 //A-family hw limitation:
1569 //If a layer need alpha scaling, MDP can not support.
1570 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1571 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1572 if(!mCurrentFrame.isFBComposed[i] &&
1573 isAlphaScaled( &list->hwLayers[i])) {
1574 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1575 return false;
1576 }
1577 }
1578 }
1579
1580 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1581 //If multiple layers requires downscaling and also they are overlapping
1582 //fall back to GPU since MDSS can not handle it.
1583 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1584 qdutils::MDPVersion::getInstance().is8x26()) {
1585 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1586 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1587 if(!mCurrentFrame.isFBComposed[i] &&
1588 isDownscaleRequired(botLayer)) {
1589 //if layer-i is marked for MDP and needs downscaling
1590 //check if any MDP layer on top of i & overlaps with layer-i
1591 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1592 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1593 if(!mCurrentFrame.isFBComposed[j] &&
1594 isDownscaleRequired(topLayer)) {
1595 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1596 topLayer->displayFrame);
1597 if(isValidRect(r))
1598 return false;
1599 }
1600 }
1601 }
1602 }
1603 }
1604 return true;
1605}
1606
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001607int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001608 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001609 char property[PROPERTY_VALUE_MAX];
1610
Raj Kamal4393eaa2014-06-06 13:45:20 +05301611 if(!ctx || !list) {
1612 ALOGE("%s: Invalid context or list",__FUNCTION__);
1613 mCachedFrame.reset();
1614 return -1;
1615 }
1616
1617 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1618
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001619 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1620 int currentFlags = atoi(property);
1621 if(currentFlags != sSimulationFlags) {
1622 sSimulationFlags = currentFlags;
1623 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1624 sSimulationFlags, sSimulationFlags);
1625 }
1626 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001627 // reset PTOR
1628 if(!mDpy)
1629 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001630
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301631 //Do not cache the information for next draw cycle.
1632 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1633 ALOGI("%s: Unsupported layer count for mdp composition",
1634 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001635 mCachedFrame.reset();
1636 return -1;
1637 }
1638
Saurabh Shahb39f8152013-08-22 10:21:44 -07001639 //reset old data
1640 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001641 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1642 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301643
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001644 // Detect the start of animation and fall back to GPU only once to cache
1645 // all the layers in FB and display FB content untill animation completes.
1646 if(ctx->listStats[mDpy].isDisplayAnimating) {
1647 mCurrentFrame.needsRedraw = false;
1648 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1649 mCurrentFrame.needsRedraw = true;
1650 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1651 }
1652 setMDPCompLayerFlags(ctx, list);
1653 mCachedFrame.updateCounts(mCurrentFrame);
1654 ret = -1;
1655 return ret;
1656 } else {
1657 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1658 }
1659
Saurabh Shahb39f8152013-08-22 10:21:44 -07001660 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001661 if(isFrameDoable(ctx)) {
1662 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001663
Raj Kamal4393eaa2014-06-06 13:45:20 +05301664 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1665 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001666 setMDPCompLayerFlags(ctx, list);
1667 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001668 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001669 reset(ctx);
1670 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1671 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001672 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001673 }
1674 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001675 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1676 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001677 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001678 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001679
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001680 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001681 ALOGD("GEOMETRY change: %d",
1682 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001683 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001684 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001685 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686 }
1687
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001688 mCachedFrame.cacheAll(list);
1689 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001690 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001691}
1692
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001693bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301694
1695 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301696 int mdpIndex = mCurrentFrame.layerToMDP[index];
1697 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1698 info.pipeInfo = new MdpYUVPipeInfo;
1699 info.rot = NULL;
1700 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301701
1702 pipe_info.lIndex = ovutils::OV_INVALID;
1703 pipe_info.rIndex = ovutils::OV_INVALID;
1704
Saurabh Shahc62f3982014-03-05 14:28:26 -08001705 Overlay::PipeSpecs pipeSpecs;
1706 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1707 pipeSpecs.needsScaling = true;
1708 pipeSpecs.dpy = mDpy;
1709 pipeSpecs.fb = false;
1710
1711 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301712 if(pipe_info.lIndex == ovutils::OV_INVALID){
1713 bRet = false;
1714 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1715 __FUNCTION__);
1716 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001717 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301718 if(pipe_info.rIndex == ovutils::OV_INVALID){
1719 bRet = false;
1720 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1721 __FUNCTION__);
1722 }
1723 return bRet;
1724}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001725
1726int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1727 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001728 if (ctx->mPtorInfo.isActive()) {
1729 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001730 if (fd < 0) {
1731 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001732 }
1733 }
1734 return fd;
1735}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001736//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001737
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001738void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301739 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001740 //If 4k2k Yuv layer split is possible, and if
1741 //fbz is above 4k2k layer, increment fb zorder by 1
1742 //as we split 4k2k layer and increment zorder for right half
1743 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001744 if(!ctx)
1745 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001746 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301747 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1748 index++) {
1749 if(!mCurrentFrame.isFBComposed[index]) {
1750 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1751 mdpNextZOrder++;
1752 }
1753 mdpNextZOrder++;
1754 hwc_layer_1_t* layer = &list->hwLayers[index];
1755 private_handle_t *hnd = (private_handle_t *)layer->handle;
1756 if(is4kx2kYuvBuffer(hnd)) {
1757 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1758 mCurrentFrame.fbZ += 1;
1759 mdpNextZOrder++;
1760 //As we split 4kx2k yuv layer and program to 2 VG pipes
1761 //(if available) increase mdpcount by 1.
1762 mCurrentFrame.mdpCount++;
1763 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001764 }
1765 }
1766 }
radhakrishnac9a67412013-09-25 17:40:42 +05301767}
1768
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001769/*
1770 * Configures pipe(s) for MDP composition
1771 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001772int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001773 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001774 MdpPipeInfoNonSplit& mdp_info =
1775 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001776 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1777 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1778 eIsFg isFg = IS_FG_OFF;
1779 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001780
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001781 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1782 __FUNCTION__, layer, zOrder, dest);
1783
Saurabh Shah88e4d272013-09-03 13:31:29 -07001784 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001785 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001786}
1787
Saurabh Shah88e4d272013-09-03 13:31:29 -07001788bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001789 hwc_display_contents_1_t* list) {
1790 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001791
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001792 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001793
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001794 hwc_layer_1_t* layer = &list->hwLayers[index];
1795 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301796 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001797 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301798 continue;
1799 }
1800 }
1801
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001802 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001803 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001804 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001805 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001806 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001807
Saurabh Shahc62f3982014-03-05 14:28:26 -08001808 Overlay::PipeSpecs pipeSpecs;
1809 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1810 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1811 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1812 (qdutils::MDPVersion::getInstance().is8x26() and
1813 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1814 pipeSpecs.dpy = mDpy;
1815 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001816 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001817
Saurabh Shahc62f3982014-03-05 14:28:26 -08001818 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1819
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001820 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001821 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001822 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001823 }
1824 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001825 return true;
1826}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001827
radhakrishnac9a67412013-09-25 17:40:42 +05301828int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1829 PipeLayerPair& PipeLayerPair) {
1830 MdpYUVPipeInfo& mdp_info =
1831 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1832 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1833 eIsFg isFg = IS_FG_OFF;
1834 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1835 eDest lDest = mdp_info.lIndex;
1836 eDest rDest = mdp_info.rIndex;
1837
1838 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1839 lDest, rDest, &PipeLayerPair.rot);
1840}
1841
Saurabh Shah88e4d272013-09-03 13:31:29 -07001842bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001843
Raj Kamal4393eaa2014-06-06 13:45:20 +05301844 if(!isEnabled() or !mModeOn) {
1845 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301846 return true;
1847 }
1848
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001849 // Set the Handle timeout to true for MDP or MIXED composition.
1850 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1851 sHandleTimeout = true;
1852 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001853
1854 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001855 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001856
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001857 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1858 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001859 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001860 if(mCurrentFrame.isFBComposed[i]) continue;
1861
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001862 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001863 private_handle_t *hnd = (private_handle_t *)layer->handle;
1864 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001865 if (!(layer->flags & HWC_COLOR_FILL)) {
1866 ALOGE("%s handle null", __FUNCTION__);
1867 return false;
1868 }
1869 // No PLAY for Color layer
1870 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1871 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001872 }
1873
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001874 int mdpIndex = mCurrentFrame.layerToMDP[i];
1875
radhakrishnac9a67412013-09-25 17:40:42 +05301876 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1877 {
1878 MdpYUVPipeInfo& pipe_info =
1879 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1880 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1881 ovutils::eDest indexL = pipe_info.lIndex;
1882 ovutils::eDest indexR = pipe_info.rIndex;
1883 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301884 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301885 if(rot) {
1886 rot->queueBuffer(fd, offset);
1887 fd = rot->getDstMemId();
1888 offset = rot->getDstOffset();
1889 }
1890 if(indexL != ovutils::OV_INVALID) {
1891 ovutils::eDest destL = (ovutils::eDest)indexL;
1892 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1893 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1894 if (!ov.queueBuffer(fd, offset, destL)) {
1895 ALOGE("%s: queueBuffer failed for display:%d",
1896 __FUNCTION__, mDpy);
1897 return false;
1898 }
1899 }
1900
1901 if(indexR != ovutils::OV_INVALID) {
1902 ovutils::eDest destR = (ovutils::eDest)indexR;
1903 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1904 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1905 if (!ov.queueBuffer(fd, offset, destR)) {
1906 ALOGE("%s: queueBuffer failed for display:%d",
1907 __FUNCTION__, mDpy);
1908 return false;
1909 }
1910 }
1911 }
1912 else{
1913 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001914 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301915 ovutils::eDest dest = pipe_info.index;
1916 if(dest == ovutils::OV_INVALID) {
1917 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001918 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301919 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001920
radhakrishnac9a67412013-09-25 17:40:42 +05301921 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1922 continue;
1923 }
1924
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001925 int fd = hnd->fd;
1926 uint32_t offset = (uint32_t)hnd->offset;
1927 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1928 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001929 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001930 fd = hnd->fd;
1931 // Use the offset of the RenderBuffer
1932 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
Sushil Chauhandefd3522014-05-13 18:17:12 -07001933 }
1934
radhakrishnac9a67412013-09-25 17:40:42 +05301935 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1936 using pipe: %d", __FUNCTION__, layer,
1937 hnd, dest );
1938
radhakrishnac9a67412013-09-25 17:40:42 +05301939 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1940 if(rot) {
1941 if(!rot->queueBuffer(fd, offset))
1942 return false;
1943 fd = rot->getDstMemId();
1944 offset = rot->getDstOffset();
1945 }
1946
1947 if (!ov.queueBuffer(fd, offset, dest)) {
1948 ALOGE("%s: queueBuffer failed for display:%d ",
1949 __FUNCTION__, mDpy);
1950 return false;
1951 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001952 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001953
1954 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001955 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001956 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001957}
1958
Saurabh Shah88e4d272013-09-03 13:31:29 -07001959//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001960
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001961void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301962 hwc_display_contents_1_t* list){
1963 //if 4kx2k yuv layer is totally present in either in left half
1964 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301965 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301966 if(mCurrentFrame.fbZ >= 0) {
1967 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1968 index++) {
1969 if(!mCurrentFrame.isFBComposed[index]) {
1970 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1971 mdpNextZOrder++;
1972 }
1973 mdpNextZOrder++;
1974 hwc_layer_1_t* layer = &list->hwLayers[index];
1975 private_handle_t *hnd = (private_handle_t *)layer->handle;
1976 if(is4kx2kYuvBuffer(hnd)) {
1977 hwc_rect_t dst = layer->displayFrame;
1978 if((dst.left > lSplit) || (dst.right < lSplit)) {
1979 mCurrentFrame.mdpCount += 1;
1980 }
1981 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1982 mCurrentFrame.fbZ += 1;
1983 mdpNextZOrder++;
1984 }
1985 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001986 }
radhakrishnac9a67412013-09-25 17:40:42 +05301987 }
1988}
1989
Saurabh Shah88e4d272013-09-03 13:31:29 -07001990bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001991 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001992
Saurabh Shahc62f3982014-03-05 14:28:26 -08001993 const int lSplit = getLeftSplit(ctx, mDpy);
1994 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001995 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001996 pipe_info.lIndex = ovutils::OV_INVALID;
1997 pipe_info.rIndex = ovutils::OV_INVALID;
1998
Saurabh Shahc62f3982014-03-05 14:28:26 -08001999 Overlay::PipeSpecs pipeSpecs;
2000 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2001 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2002 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2003 pipeSpecs.dpy = mDpy;
2004 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2005 pipeSpecs.fb = false;
2006
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002007 // Acquire pipe only for the updating half
2008 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2009 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2010
2011 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002012 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002013 if(pipe_info.lIndex == ovutils::OV_INVALID)
2014 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002015 }
2016
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002017 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002018 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2019 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002020 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002021 return false;
2022 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002023
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002024 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002025}
2026
Saurabh Shah88e4d272013-09-03 13:31:29 -07002027bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002028 hwc_display_contents_1_t* list) {
2029 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002030
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002031 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002032
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002033 hwc_layer_1_t* layer = &list->hwLayers[index];
2034 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302035 hwc_rect_t dst = layer->displayFrame;
2036 const int lSplit = getLeftSplit(ctx, mDpy);
2037 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
2038 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002039 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302040 continue;
2041 }
2042 }
2043 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002044 int mdpIndex = mCurrentFrame.layerToMDP[index];
2045 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002046 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002047 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002048 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002049
Saurabh Shahc62f3982014-03-05 14:28:26 -08002050 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2051 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2052 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002053 return false;
2054 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002055 }
2056 return true;
2057}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002058
radhakrishnac9a67412013-09-25 17:40:42 +05302059int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2060 PipeLayerPair& PipeLayerPair) {
2061 const int lSplit = getLeftSplit(ctx, mDpy);
2062 hwc_rect_t dst = layer->displayFrame;
2063 if((dst.left > lSplit)||(dst.right < lSplit)){
2064 MdpYUVPipeInfo& mdp_info =
2065 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2066 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2067 eIsFg isFg = IS_FG_OFF;
2068 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2069 eDest lDest = mdp_info.lIndex;
2070 eDest rDest = mdp_info.rIndex;
2071
2072 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2073 lDest, rDest, &PipeLayerPair.rot);
2074 }
2075 else{
2076 return configure(ctx, layer, PipeLayerPair);
2077 }
2078}
2079
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002080/*
2081 * Configures pipe(s) for MDP composition
2082 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002083int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002084 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002085 MdpPipeInfoSplit& mdp_info =
2086 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002087 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2088 eIsFg isFg = IS_FG_OFF;
2089 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2090 eDest lDest = mdp_info.lIndex;
2091 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002092
2093 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2094 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2095
Saurabh Shah88e4d272013-09-03 13:31:29 -07002096 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002097 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002098}
2099
Saurabh Shah88e4d272013-09-03 13:31:29 -07002100bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002101
Raj Kamal4393eaa2014-06-06 13:45:20 +05302102 if(!isEnabled() or !mModeOn) {
2103 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302104 return true;
2105 }
2106
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002107 // Set the Handle timeout to true for MDP or MIXED composition.
2108 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2109 sHandleTimeout = true;
2110 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002111
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002112 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002113 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002114
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002115 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2116 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002117 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002118 if(mCurrentFrame.isFBComposed[i]) continue;
2119
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002120 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002121 private_handle_t *hnd = (private_handle_t *)layer->handle;
2122 if(!hnd) {
2123 ALOGE("%s handle null", __FUNCTION__);
2124 return false;
2125 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002126
2127 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2128 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002129 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002130
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002131 int mdpIndex = mCurrentFrame.layerToMDP[i];
2132
radhakrishnac9a67412013-09-25 17:40:42 +05302133 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2134 {
2135 MdpYUVPipeInfo& pipe_info =
2136 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2137 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2138 ovutils::eDest indexL = pipe_info.lIndex;
2139 ovutils::eDest indexR = pipe_info.rIndex;
2140 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302141 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302142 if(rot) {
2143 rot->queueBuffer(fd, offset);
2144 fd = rot->getDstMemId();
2145 offset = rot->getDstOffset();
2146 }
2147 if(indexL != ovutils::OV_INVALID) {
2148 ovutils::eDest destL = (ovutils::eDest)indexL;
2149 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2150 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2151 if (!ov.queueBuffer(fd, offset, destL)) {
2152 ALOGE("%s: queueBuffer failed for display:%d",
2153 __FUNCTION__, mDpy);
2154 return false;
2155 }
2156 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002157
radhakrishnac9a67412013-09-25 17:40:42 +05302158 if(indexR != ovutils::OV_INVALID) {
2159 ovutils::eDest destR = (ovutils::eDest)indexR;
2160 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2161 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2162 if (!ov.queueBuffer(fd, offset, destR)) {
2163 ALOGE("%s: queueBuffer failed for display:%d",
2164 __FUNCTION__, mDpy);
2165 return false;
2166 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002167 }
2168 }
radhakrishnac9a67412013-09-25 17:40:42 +05302169 else{
2170 MdpPipeInfoSplit& pipe_info =
2171 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2172 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002173
radhakrishnac9a67412013-09-25 17:40:42 +05302174 ovutils::eDest indexL = pipe_info.lIndex;
2175 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002176
radhakrishnac9a67412013-09-25 17:40:42 +05302177 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002178 uint32_t offset = (uint32_t)hnd->offset;
2179 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2180 if (!mDpy && (index != -1)) {
2181 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2182 fd = hnd->fd;
2183 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
2184 }
radhakrishnac9a67412013-09-25 17:40:42 +05302185
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002186 if(ctx->mAD->draw(ctx, fd, offset)) {
2187 fd = ctx->mAD->getDstFd();
2188 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002189 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002190
radhakrishnac9a67412013-09-25 17:40:42 +05302191 if(rot) {
2192 rot->queueBuffer(fd, offset);
2193 fd = rot->getDstMemId();
2194 offset = rot->getDstOffset();
2195 }
2196
2197 //************* play left mixer **********
2198 if(indexL != ovutils::OV_INVALID) {
2199 ovutils::eDest destL = (ovutils::eDest)indexL;
2200 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2201 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2202 if (!ov.queueBuffer(fd, offset, destL)) {
2203 ALOGE("%s: queueBuffer failed for left mixer",
2204 __FUNCTION__);
2205 return false;
2206 }
2207 }
2208
2209 //************* play right mixer **********
2210 if(indexR != ovutils::OV_INVALID) {
2211 ovutils::eDest destR = (ovutils::eDest)indexR;
2212 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2213 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2214 if (!ov.queueBuffer(fd, offset, destR)) {
2215 ALOGE("%s: queueBuffer failed for right mixer",
2216 __FUNCTION__);
2217 return false;
2218 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002219 }
2220 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002221
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002222 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2223 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002224
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002225 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002226}
Saurabh Shahab47c692014-02-12 18:45:57 -08002227
2228//================MDPCompSrcSplit==============================================
2229bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002230 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002231 private_handle_t *hnd = (private_handle_t *)layer->handle;
2232 hwc_rect_t dst = layer->displayFrame;
2233 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2234 pipe_info.lIndex = ovutils::OV_INVALID;
2235 pipe_info.rIndex = ovutils::OV_INVALID;
2236
2237 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2238 //should have a higher priority than the right one. Pipe priorities are
2239 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002240
Saurabh Shahc62f3982014-03-05 14:28:26 -08002241 Overlay::PipeSpecs pipeSpecs;
2242 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2243 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2244 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2245 pipeSpecs.dpy = mDpy;
2246 pipeSpecs.fb = false;
2247
Saurabh Shahab47c692014-02-12 18:45:57 -08002248 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002249 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002250 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002251 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002252 }
2253
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002254 /* Use 2 pipes IF
2255 a) Layer's crop width is > 2048 or
2256 b) Layer's dest width > 2048 or
2257 c) On primary, driver has indicated with caps to split always. This is
2258 based on an empirically derived value of panel height. Applied only
2259 if the layer's width is > mixer's width
2260 */
2261
2262 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2263 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2264 int lSplit = getLeftSplit(ctx, mDpy);
2265 int dstWidth = dst.right - dst.left;
2266 int cropWidth = crop.right - crop.left;
2267
2268 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2269 cropWidth > qdutils::MAX_DISPLAY_DIM or
2270 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002271 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002272 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002273 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002274 }
2275
2276 // Return values
2277 // 1 Left pipe is higher priority, do nothing.
2278 // 0 Pipes of same priority.
2279 //-1 Right pipe is of higher priority, needs swap.
2280 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2281 pipe_info.rIndex) == -1) {
2282 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002283 }
2284 }
2285
2286 return true;
2287}
2288
Saurabh Shahab47c692014-02-12 18:45:57 -08002289int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2290 PipeLayerPair& PipeLayerPair) {
2291 private_handle_t *hnd = (private_handle_t *)layer->handle;
2292 if(!hnd) {
2293 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2294 return -1;
2295 }
2296 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2297 MdpPipeInfoSplit& mdp_info =
2298 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2299 Rotator **rot = &PipeLayerPair.rot;
2300 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2301 eIsFg isFg = IS_FG_OFF;
2302 eDest lDest = mdp_info.lIndex;
2303 eDest rDest = mdp_info.rIndex;
2304 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2305 hwc_rect_t dst = layer->displayFrame;
2306 int transform = layer->transform;
2307 eTransform orient = static_cast<eTransform>(transform);
2308 const int downscale = 0;
2309 int rotFlags = ROT_FLAGS_NONE;
2310 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2311 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2312
2313 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2314 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2315
2316 // Handle R/B swap
2317 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2318 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2319 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2320 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2321 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2322 }
2323
Saurabh Shah97e2d802014-04-14 18:03:54 -07002324 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002325 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002326
2327 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2328 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002329 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002330 }
2331
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002332 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002333 (*rot) = ctx->mRotMgr->getNext();
2334 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002335 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002336 //If the video is using a single pipe, enable BWC
2337 if(rDest == OV_INVALID) {
2338 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2339 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002340 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002341 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002342 ALOGE("%s: configRotator failed!", __FUNCTION__);
2343 return -1;
2344 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002345 updateSource(orient, whf, crop, *rot);
Saurabh Shahab47c692014-02-12 18:45:57 -08002346 rotFlags |= ROT_PREROTATED;
2347 }
2348
2349 //If 2 pipes being used, divide layer into half, crop and dst
2350 hwc_rect_t cropL = crop;
2351 hwc_rect_t cropR = crop;
2352 hwc_rect_t dstL = dst;
2353 hwc_rect_t dstR = dst;
2354 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2355 cropL.right = (crop.right + crop.left) / 2;
2356 cropR.left = cropL.right;
2357 sanitizeSourceCrop(cropL, cropR, hnd);
2358
2359 //Swap crops on H flip since 2 pipes are being used
2360 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2361 hwc_rect_t tmp = cropL;
2362 cropL = cropR;
2363 cropR = tmp;
2364 }
2365
2366 dstL.right = (dst.right + dst.left) / 2;
2367 dstR.left = dstL.right;
2368 }
2369
2370 //For the mdp, since either we are pre-rotating or MDP does flips
2371 orient = OVERLAY_TRANSFORM_0;
2372 transform = 0;
2373
2374 //configure left pipe
2375 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002376 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002377 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2378 (ovutils::eBlending) getBlending(layer->blending));
2379
2380 if(configMdp(ctx->mOverlay, pargL, orient,
2381 cropL, dstL, metadata, lDest) < 0) {
2382 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2383 return -1;
2384 }
2385 }
2386
2387 //configure right pipe
2388 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002389 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002390 static_cast<eRotFlags>(rotFlags),
2391 layer->planeAlpha,
2392 (ovutils::eBlending) getBlending(layer->blending));
2393 if(configMdp(ctx->mOverlay, pargR, orient,
2394 cropR, dstR, metadata, rDest) < 0) {
2395 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2396 return -1;
2397 }
2398 }
2399
2400 return 0;
2401}
2402
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002403}; //namespace
2404