blob: 26cf27d7a001dd7919ca9e3df926f9449380d872 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
138 // Idle invalidation is not necessary on command mode panels
139 long idle_timeout = DEFAULT_IDLE_TIME;
140 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
141 if(atoi(property) != 0)
142 idle_timeout = atoi(property);
143 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800144
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400145 //create Idle Invalidator only when not disabled through property
146 if(idle_timeout != -1)
147 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800148
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400149 if(idleInvalidator == NULL) {
150 ALOGE("%s: failed to instantiate idleInvalidator object",
151 __FUNCTION__);
152 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530153 idleInvalidator->init(timeout_handler, ctx,
154 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400155 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800156 }
radhakrishnac9a67412013-09-25 17:40:42 +0530157
Saurabh Shah7c727642014-06-02 15:47:14 -0700158 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700159 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700160 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
161 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
162 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530163 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530164 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700165
166 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
167 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
168 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
169 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
170 HWC_DISPLAY_PRIMARY);
171 }
172
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700173 return true;
174}
175
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800176void MDPComp::reset(hwc_context_t *ctx) {
177 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700178 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800179 ctx->mOverlay->clear(mDpy);
180 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700181}
182
Raj Kamal4393eaa2014-06-06 13:45:20 +0530183void MDPComp::reset() {
184 sHandleTimeout = false;
185 mModeOn = false;
186}
187
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700188void MDPComp::timeout_handler(void *udata) {
189 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
190
191 if(!ctx) {
192 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
193 return;
194 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800195 Locker::Autolock _l(ctx->mDrawLock);
196 // Handle timeout event only if the previous composition is MDP or MIXED.
197 if(!sHandleTimeout) {
198 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
199 return;
200 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700201 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700202 ALOGE("%s: HWC proc not registered", __FUNCTION__);
203 return;
204 }
205 sIdleFallBack = true;
206 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700207 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700208}
209
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800210void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800211 hwc_display_contents_1_t* list) {
212 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800213
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800214 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800215 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800216 if(!mCurrentFrame.isFBComposed[index]) {
217 layerProp[index].mFlags |= HWC_MDPCOMP;
218 layer->compositionType = HWC_OVERLAY;
219 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700221 /* Drop the layer when its already present in FB OR when it lies
222 * outside frame's ROI */
223 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800224 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700225 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800226 }
227 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500229
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800230void MDPComp::setRedraw(hwc_context_t *ctx,
231 hwc_display_contents_1_t* list) {
232 mCurrentFrame.needsRedraw = false;
233 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
234 (list->flags & HWC_GEOMETRY_CHANGED) ||
235 isSkipPresent(ctx, mDpy)) {
236 mCurrentFrame.needsRedraw = true;
237 }
238}
239
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800240MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700241 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800242}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800243
Saurabh Shahaa236822013-04-24 18:07:26 -0700244void MDPComp::FrameInfo::reset(const int& numLayers) {
245 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246 if(mdpToLayer[i].pipeInfo) {
247 delete mdpToLayer[i].pipeInfo;
248 mdpToLayer[i].pipeInfo = NULL;
249 //We dont own the rotator
250 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800251 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800252 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800253
254 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
255 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700256 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
Saurabh Shahaa236822013-04-24 18:07:26 -0700258 layerCount = numLayers;
259 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700261 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800262 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263}
264
Saurabh Shahaa236822013-04-24 18:07:26 -0700265void MDPComp::FrameInfo::map() {
266 // populate layer and MDP maps
267 int mdpIdx = 0;
268 for(int idx = 0; idx < layerCount; idx++) {
269 if(!isFBComposed[idx]) {
270 mdpToLayer[mdpIdx].listIndex = idx;
271 layerToMDP[idx] = mdpIdx++;
272 }
273 }
274}
275
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800276MDPComp::LayerCache::LayerCache() {
277 reset();
278}
279
280void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700281 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530282 memset(&isFBComposed, true, sizeof(isFBComposed));
283 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800284 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700285}
286
287void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530288 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289 for(int i = 0; i < numAppLayers; i++) {
290 hnd[i] = list->hwLayers[i].handle;
291 }
292}
293
294void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530296 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
297 memcpy(&drop, &curFrame.drop, sizeof(drop));
298}
299
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800300bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
301 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530302 if(layerCount != curFrame.layerCount)
303 return false;
304 for(int i = 0; i < curFrame.layerCount; i++) {
305 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
306 (curFrame.drop[i] != drop[i])) {
307 return false;
308 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800309 if(curFrame.isFBComposed[i] &&
310 (hnd[i] != list->hwLayers[i].handle)){
311 return false;
312 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530313 }
314 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800315}
316
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700317bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800319 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700320 (not isValidDimension(ctx,layer))
321 //More conditions here, SKIP, sRGB+Blend etc
322 ) {
323 return false;
324 }
325 return true;
326}
327
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530328bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800329 private_handle_t *hnd = (private_handle_t *)layer->handle;
330
331 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700332 if (layer->flags & HWC_COLOR_FILL) {
333 // Color layer
334 return true;
335 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800336 ALOGE("%s: layer handle is NULL", __FUNCTION__);
337 return false;
338 }
339
Naseer Ahmede850a802013-09-06 13:12:52 -0400340 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400341 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400342 return false;
343
Saurabh Shah62e1d732013-09-17 10:44:05 -0700344 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700345 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700346 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700347 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
348 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 int dst_w = dst.right - dst.left;
350 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800351 float w_scale = ((float)crop_w / (float)dst_w);
352 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530353 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700354
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800355 /* Workaround for MDP HW limitation in DSI command mode panels where
356 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
357 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530358 * There also is a HW limilation in MDP, minimum block size is 2x2
359 * Fallback to GPU if height is less than 2.
360 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800361 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800362 return false;
363
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800364 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530365 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800366 const float w_dscale = w_scale;
367 const float h_dscale = h_scale;
368
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800369 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700370
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530371 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700372 /* On targets that doesnt support Decimation (eg.,8x26)
373 * maximum downscale support is overlay pipe downscale.
374 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530375 if(crop_w > mdpHw.getMaxMixerWidth() ||
376 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700377 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800378 return false;
379 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700380 // Decimation on macrotile format layers is not supported.
381 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530382 /* Bail out if
383 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700384 * 2. exceeds maximum downscale limit
385 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530386 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
387 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700388 w_dscale > maxMDPDownscale ||
389 h_dscale > maxMDPDownscale) {
390 return false;
391 }
392 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800393 return false;
394 }
395 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 return false;
398 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 }
400
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800401 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530402 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 const float w_uscale = 1.0f / w_scale;
404 const float h_uscale = 1.0f / h_scale;
405
406 if(w_uscale > upscale || h_uscale > upscale)
407 return false;
408 }
409
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return true;
411}
412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800413bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700414 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416 if(!isEnabled()) {
417 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530419 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530420 qdutils::MDPVersion::getInstance().is8x16() ||
421 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800422 ctx->mVideoTransFlag &&
423 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700424 //1 Padding round to shift pipes across mixers
425 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
426 __FUNCTION__);
427 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800428 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800429 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800430 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700431 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700432 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530433 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
434 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700436 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700437 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800438}
439
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800440void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
441 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
442 fbRect = getIntersection(fbRect, roi);
443}
444
445/* 1) Identify layers that are not visible or lying outside the updating ROI and
446 * drop them from composition.
447 * 2) If we have a scaling layer which needs cropping against generated
448 * ROI, reset ROI to full resolution. */
449bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
450 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700451 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800452 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800453
454 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800455 if(!isValidRect(visibleRect)) {
456 mCurrentFrame.drop[i] = true;
457 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800458 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800459 }
460
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700461 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700462 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800463 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 if(!isValidRect(res)) {
466 mCurrentFrame.drop[i] = true;
467 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800468 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 /* Reset frame ROI when any layer which needs scaling also needs ROI
470 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800471 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800472 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700473 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
474 mCurrentFrame.dropCount = 0;
475 return false;
476 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800477
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800478 /* deduct any opaque region from visibleRect */
479 if (layer->blending == HWC_BLENDING_NONE)
480 visibleRect = deductRect(visibleRect, res);
481 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700482 }
483 return true;
484}
485
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800486/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
487 * are updating. If DirtyRegion is applicable, calculate it by accounting all
488 * the changing layer's dirtyRegion. */
489void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
490 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700491 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800492 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700493 return;
494
495 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
497 (int)ctx->dpyAttr[mDpy].yres};
498
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700499 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800500 hwc_layer_1_t* layer = &list->hwLayers[index];
501 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800502 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700503 hwc_rect_t dst = layer->displayFrame;
504 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800505
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800506#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800507 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700508 {
509 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
510 int x_off = dst.left - src.left;
511 int y_off = dst.top - src.top;
512 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
513 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800514#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800515
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800516 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700517 }
518 }
519
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800520 /* No layer is updating. Still SF wants a refresh.*/
521 if(!isValidRect(roi))
522 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800523
524 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800525 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800526
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527 ctx->listStats[mDpy].lRoi = roi;
528 if(!validateAndApplyROI(ctx, list))
529 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700530
531 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800532 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
533 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
534}
535
536void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
537 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
538 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
539
540 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
541 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
542 fbRect = getUnion(l_fbRect, r_fbRect);
543}
544/* 1) Identify layers that are not visible or lying outside BOTH the updating
545 * ROI's and drop them from composition. If a layer is spanning across both
546 * the halves of the screen but needed by only ROI, the non-contributing
547 * half will not be programmed for MDP.
548 * 2) If we have a scaling layer which needs cropping against generated
549 * ROI, reset ROI to full resolution. */
550bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
551 hwc_display_contents_1_t* list) {
552
553 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
554
555 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
556 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
557
558 for(int i = numAppLayers - 1; i >= 0; i--){
559 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
560 {
561 mCurrentFrame.drop[i] = true;
562 mCurrentFrame.dropCount++;
563 continue;
564 }
565
566 const hwc_layer_1_t* layer = &list->hwLayers[i];
567 hwc_rect_t dstRect = layer->displayFrame;
568
569 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
570 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
571 hwc_rect_t res = getUnion(l_res, r_res);
572
573 if(!isValidRect(l_res) && !isValidRect(r_res)) {
574 mCurrentFrame.drop[i] = true;
575 mCurrentFrame.dropCount++;
576 } else {
577 /* Reset frame ROI when any layer which needs scaling also needs ROI
578 * cropping */
579 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
580 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
581 mCurrentFrame.dropCount = 0;
582 return false;
583 }
584
585 if (layer->blending == HWC_BLENDING_NONE) {
586 visibleRectL = deductRect(visibleRectL, l_res);
587 visibleRectR = deductRect(visibleRectR, r_res);
588 }
589 }
590 }
591 return true;
592}
593/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
594 * are updating. If DirtyRegion is applicable, calculate it by accounting all
595 * the changing layer's dirtyRegion. */
596void MDPCompSplit::generateROI(hwc_context_t *ctx,
597 hwc_display_contents_1_t* list) {
598 if(!canPartialUpdate(ctx, list))
599 return;
600
601 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
602 int lSplit = getLeftSplit(ctx, mDpy);
603
604 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
605 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
606
607 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
608 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
609
610 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
611 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
612
613 for(int index = 0; index < numAppLayers; index++ ) {
614 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800615 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800616 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800617 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700618 hwc_rect_t dst = layer->displayFrame;
619 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800620
621#ifdef QCOM_BSP
622 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700623 {
624 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
625 int x_off = dst.left - src.left;
626 int y_off = dst.top - src.top;
627 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
628 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800629#endif
630
631 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
632 if(isValidRect(l_dst))
633 l_roi = getUnion(l_roi, l_dst);
634
635 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
636 if(isValidRect(r_dst))
637 r_roi = getUnion(r_roi, r_dst);
638 }
639 }
640
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700641 /* For panels that cannot accept commands in both the interfaces, we cannot
642 * send two ROI's (for each half). We merge them into single ROI and split
643 * them across lSplit for MDP mixer use. The ROI's will be merged again
644 * finally before udpating the panel in the driver. */
645 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
646 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
647 l_roi = getIntersection(temp_roi, l_frame);
648 r_roi = getIntersection(temp_roi, r_frame);
649 }
650
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800651 /* No layer is updating. Still SF wants a refresh. */
652 if(!isValidRect(l_roi) && !isValidRect(r_roi))
653 return;
654
655 l_roi = getSanitizeROI(l_roi, l_frame);
656 r_roi = getSanitizeROI(r_roi, r_frame);
657
658 ctx->listStats[mDpy].lRoi = l_roi;
659 ctx->listStats[mDpy].rRoi = r_roi;
660
661 if(!validateAndApplyROI(ctx, list))
662 resetROI(ctx, mDpy);
663
664 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
665 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
666 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
667 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
668 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
669 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700670}
671
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800672/* Checks for conditions where all the layers marked for MDP comp cannot be
673 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800674bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800675 hwc_display_contents_1_t* list){
676
Saurabh Shahaa236822013-04-24 18:07:26 -0700677 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800678 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800679
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700680 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700681 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
682 return false;
683 }
684
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800685 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700686 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
687 __FUNCTION__,
688 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800689 return false;
690 }
691
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530692 MDPVersion& mdpHw = MDPVersion::getInstance();
693 if(mDpy > HWC_DISPLAY_PRIMARY &&
694 (priDispW > mdpHw.getMaxMixerWidth()) &&
695 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800696 // Disable MDP comp on Secondary when the primary is highres panel and
697 // the secondary is a normal 1080p, because, MDP comp on secondary under
698 // in such usecase, decimation gets used for downscale and there will be
699 // a quality mismatch when there will be a fallback to GPU comp
700 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
701 __FUNCTION__);
702 return false;
703 }
704
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800705 // check for action safe flag and downscale mode which requires scaling.
706 if(ctx->dpyAttr[mDpy].mActionSafePresent
707 || ctx->dpyAttr[mDpy].mDownScaleMode) {
708 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
709 return false;
710 }
711
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800712 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800713 hwc_layer_1_t* layer = &list->hwLayers[i];
714 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800715
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800716 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700717 if(!canUseRotator(ctx, mDpy)) {
718 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
719 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700720 return false;
721 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800722 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530723
724 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
725 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700726 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530727 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
728 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
729 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800730 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700731
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700732 if(ctx->mAD->isDoable()) {
733 return false;
734 }
735
Saurabh Shahaa236822013-04-24 18:07:26 -0700736 //If all above hard conditions are met we can do full or partial MDP comp.
737 bool ret = false;
738 if(fullMDPComp(ctx, list)) {
739 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700740 } else if(fullMDPCompWithPTOR(ctx, list)) {
741 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700742 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700743 ret = true;
744 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530745
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 return ret;
747}
748
749bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700750
751 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
752 return false;
753
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700754 //Will benefit presentation / secondary-only layer.
755 if((mDpy > HWC_DISPLAY_PRIMARY) &&
756 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
757 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
758 return false;
759 }
760
761 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
762 for(int i = 0; i < numAppLayers; i++) {
763 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700764 if(not mCurrentFrame.drop[i] and
765 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700766 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
767 return false;
768 }
769 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800770
Saurabh Shahaa236822013-04-24 18:07:26 -0700771 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700772 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
773 sizeof(mCurrentFrame.isFBComposed));
774 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
775 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700776
Raj Kamal389d6e32014-08-04 14:43:24 +0530777 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800778 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530779 }
780
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800781 if(!postHeuristicsHandling(ctx, list)) {
782 ALOGD_IF(isDebug(), "post heuristic handling failed");
783 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700784 return false;
785 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700786 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
787 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700788 return true;
789}
790
Sushil Chauhandefd3522014-05-13 18:17:12 -0700791/* Full MDP Composition with Peripheral Tiny Overlap Removal.
792 * MDP bandwidth limitations can be avoided, if the overlap region
793 * covered by the smallest layer at a higher z-order, gets composed
794 * by Copybit on a render buffer, which can be queued to MDP.
795 */
796bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
797 hwc_display_contents_1_t* list) {
798
799 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
800 const int stagesForMDP = min(sMaxPipesPerMixer,
801 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
802
803 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700804 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700805 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
806 return false;
807 }
808
809 // Frame level checks
810 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
811 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
812 isSecurePresent(ctx, mDpy)) {
813 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
814 return false;
815 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700816 // MDP comp checks
817 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700818 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700819 if(not isSupportedForMDPComp(ctx, layer)) {
820 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
821 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700822 }
823 }
824
Sushil Chauhandefd3522014-05-13 18:17:12 -0700825 /* We cannot use this composition mode, if:
826 1. A below layer needs scaling.
827 2. Overlap is not peripheral to display.
828 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700829 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700830 */
831
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700832 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
833 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
834 memset(overlapRect, 0, sizeof(overlapRect));
835 int layerPixelCount, minPixelCount = 0;
836 int numPTORLayersFound = 0;
837 for (int i = numAppLayers-1; (i >= 0 &&
838 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700839 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700840 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700841 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700842 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
843 // PTOR layer should be peripheral and cannot have transform
844 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
845 has90Transform(layer)) {
846 continue;
847 }
848 if((3 * (layerPixelCount + minPixelCount)) >
849 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
850 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
851 continue;
852 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700853 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700854 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;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700858 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700859 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700860 if (isValidRect(getIntersection(dispFrame, disFrame))) {
861 if (has90Transform(layer) || needsScaling(layer)) {
862 found = false;
863 break;
864 }
865 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700866 }
867 }
868 // Store the minLayer Index
869 if(found) {
870 minLayerIndex[numPTORLayersFound] = i;
871 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
872 minPixelCount += layerPixelCount;
873 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700874 }
875 }
876
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700877 // No overlap layers
878 if (!numPTORLayersFound)
879 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700880
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700881 // Store the displayFrame and the sourceCrops of the layers
882 hwc_rect_t displayFrame[numAppLayers];
883 hwc_rect_t sourceCrop[numAppLayers];
884 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700885 hwc_layer_1_t* layer = &list->hwLayers[i];
886 displayFrame[i] = layer->displayFrame;
887 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700889
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530890 /**
891 * It's possible that 2 PTOR layers might have overlapping.
892 * In such case, remove the intersection(again if peripheral)
893 * from the lower PTOR layer to avoid overlapping.
894 * If intersection is not on peripheral then compromise
895 * by reducing number of PTOR layers.
896 **/
897 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
898 if(isValidRect(commonRect)) {
899 overlapRect[1] = deductRect(overlapRect[1], commonRect);
900 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
901 }
902
903 ctx->mPtorInfo.count = numPTORLayersFound;
904 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
905 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
906 }
907
908 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
909 // reset PTOR
910 ctx->mPtorInfo.count = 0;
911 if(isValidRect(commonRect)) {
912 // If PTORs are intersecting restore displayframe of PTOR[1]
913 // before returning, as we have modified it above.
914 list->hwLayers[minLayerIndex[1]].displayFrame =
915 displayFrame[minLayerIndex[1]];
916 }
917 return false;
918 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700919 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
920 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
921
Xu Yangcda012c2014-07-30 21:57:21 +0800922 // Store the blending mode, planeAlpha, and transform of PTOR layers
923 int32_t blending[numPTORLayersFound];
924 uint8_t planeAlpha[numPTORLayersFound];
925 uint32_t transform[numPTORLayersFound];
926
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700927 for(int j = 0; j < numPTORLayersFound; j++) {
928 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700929
930 // Update src crop of PTOR layer
931 hwc_layer_1_t* layer = &list->hwLayers[index];
932 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
933 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
934 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
935 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
936
937 // Store & update w, h, format of PTOR layer
938 private_handle_t *hnd = (private_handle_t *)layer->handle;
939 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
940 layerWhf[j] = whf;
941 hnd->width = renderBuf->width;
942 hnd->height = renderBuf->height;
943 hnd->format = renderBuf->format;
944
Xu Yangcda012c2014-07-30 21:57:21 +0800945 // Store & update blending mode, planeAlpha and transform of PTOR layer
946 blending[j] = layer->blending;
947 planeAlpha[j] = layer->planeAlpha;
948 transform[j] = layer->transform;
949 layer->blending = HWC_BLENDING_NONE;
950 layer->planeAlpha = 0xFF;
951 layer->transform = 0;
952
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700953 // Remove overlap from crop & displayFrame of below layers
954 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700955 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 if(!isValidRect(getIntersection(layer->displayFrame,
957 overlapRect[j]))) {
958 continue;
959 }
960 // Update layer attributes
961 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
962 hwc_rect_t destRect = deductRect(layer->displayFrame,
963 overlapRect[j]);
964 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
965 layer->transform);
966 layer->sourceCropf.left = (float)srcCrop.left;
967 layer->sourceCropf.top = (float)srcCrop.top;
968 layer->sourceCropf.right = (float)srcCrop.right;
969 layer->sourceCropf.bottom = (float)srcCrop.bottom;
970 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700971 }
972
973 mCurrentFrame.mdpCount = numAppLayers;
974 mCurrentFrame.fbCount = 0;
975 mCurrentFrame.fbZ = -1;
976
977 for (int j = 0; j < numAppLayers; j++)
978 mCurrentFrame.isFBComposed[j] = false;
979
980 bool result = postHeuristicsHandling(ctx, list);
981
982 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700984 hwc_layer_1_t* layer = &list->hwLayers[i];
985 layer->displayFrame = displayFrame[i];
986 layer->sourceCropf.left = (float)sourceCrop[i].left;
987 layer->sourceCropf.top = (float)sourceCrop[i].top;
988 layer->sourceCropf.right = (float)sourceCrop[i].right;
989 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
990 }
991
Xu Yangcda012c2014-07-30 21:57:21 +0800992 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700993 for (int i = 0; i < numPTORLayersFound; i++) {
994 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +0800995 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700996 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
997 hnd->width = layerWhf[i].w;
998 hnd->height = layerWhf[i].h;
999 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001000 layer->blending = blending[i];
1001 layer->planeAlpha = planeAlpha[i];
1002 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001003 }
1004
Sushil Chauhandefd3522014-05-13 18:17:12 -07001005 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001006 // reset PTOR
1007 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001008 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001009 } else {
1010 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1011 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001012 }
1013
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001014 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1015 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001016 return result;
1017}
1018
Saurabh Shahaa236822013-04-24 18:07:26 -07001019bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1020{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001021 if(!sEnableMixedMode) {
1022 //Mixed mode is disabled. No need to even try caching.
1023 return false;
1024 }
1025
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001026 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001027 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001028 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001029 cacheBasedComp(ctx, list);
1030 } else {
1031 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001032 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001033 }
1034
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001035 return ret;
1036}
1037
1038bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1039 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001040 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1041 return false;
1042
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001043 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001044 mCurrentFrame.reset(numAppLayers);
1045 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001046
1047 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1048 for(int i = 0; i < numAppLayers; i++) {
1049 if(!mCurrentFrame.isFBComposed[i]) {
1050 hwc_layer_1_t* layer = &list->hwLayers[i];
1051 if(not isSupportedForMDPComp(ctx, layer)) {
1052 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1053 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001054 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001055 return false;
1056 }
1057 }
1058 }
1059
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001060 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301061 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001062 if(!ret) {
1063 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001064 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001065 return false;
1066 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001067
1068 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001069
Raj Kamal389d6e32014-08-04 14:43:24 +05301070 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001071 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301072 }
1073
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001074 //Will benefit cases where a video has non-updating background.
1075 if((mDpy > HWC_DISPLAY_PRIMARY) and
1076 (mdpCount > MAX_SEC_LAYERS)) {
1077 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001078 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001079 return false;
1080 }
1081
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001082 if(!postHeuristicsHandling(ctx, list)) {
1083 ALOGD_IF(isDebug(), "post heuristic handling failed");
1084 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001085 return false;
1086 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001087 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1088 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001089
Saurabh Shahaa236822013-04-24 18:07:26 -07001090 return true;
1091}
1092
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001093bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001094 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001095 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1096 return false;
1097
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001098 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001099 return false;
1100 }
1101
Saurabh Shahb772ae32013-11-18 15:40:02 -08001102 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001103 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1104 const int stagesForMDP = min(sMaxPipesPerMixer,
1105 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001106
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001107 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1108 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1109 int lastMDPSupportedIndex = numAppLayers;
1110 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001111
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001112 //Find the minimum MDP batch size
1113 for(int i = 0; i < numAppLayers;i++) {
1114 if(mCurrentFrame.drop[i]) {
1115 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001116 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001117 }
1118 hwc_layer_1_t* layer = &list->hwLayers[i];
1119 if(not isSupportedForMDPComp(ctx, layer)) {
1120 lastMDPSupportedIndex = i;
1121 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1122 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001123 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001124 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001125 }
1126
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001127 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1128 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1129 mCurrentFrame.dropCount);
1130
1131 //Start at a point where the fb batch should at least have 2 layers, for
1132 //this mode to be justified.
1133 while(fbBatchSize < 2) {
1134 ++fbBatchSize;
1135 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001136 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001137
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001138 //If there are no layers for MDP, this mode doesnt make sense.
1139 if(mdpBatchSize < 1) {
1140 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1141 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001142 return false;
1143 }
1144
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001145 mCurrentFrame.reset(numAppLayers);
1146
1147 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1148 while(mdpBatchSize > 0) {
1149 //Mark layers for MDP comp
1150 int mdpBatchLeft = mdpBatchSize;
1151 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1152 if(mCurrentFrame.drop[i]) {
1153 continue;
1154 }
1155 mCurrentFrame.isFBComposed[i] = false;
1156 --mdpBatchLeft;
1157 }
1158
1159 mCurrentFrame.fbZ = mdpBatchSize;
1160 mCurrentFrame.fbCount = fbBatchSize;
1161 mCurrentFrame.mdpCount = mdpBatchSize;
1162
1163 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1164 __FUNCTION__, mdpBatchSize, fbBatchSize,
1165 mCurrentFrame.dropCount);
1166
1167 if(postHeuristicsHandling(ctx, list)) {
1168 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001169 __FUNCTION__);
1170 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1171 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001172 return true;
1173 }
1174
1175 reset(ctx);
1176 --mdpBatchSize;
1177 ++fbBatchSize;
1178 }
1179
1180 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001181}
1182
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001183bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301184 if(mDpy or isSecurePresent(ctx, mDpy) or
1185 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001186 return false;
1187 }
1188 return true;
1189}
1190
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001191bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1192 hwc_display_contents_1_t* list){
1193 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1194 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1195 mDpy ) {
1196 return false;
1197 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001198 if(ctx->listStats[mDpy].secureUI)
1199 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001200 return true;
1201}
1202
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001203bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1204 hwc_display_contents_1_t* list) {
1205 const bool secureOnly = true;
1206 return videoOnlyComp(ctx, list, not secureOnly) or
1207 videoOnlyComp(ctx, list, secureOnly);
1208}
1209
1210bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001211 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001212 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1213 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001214 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001215
Saurabh Shahaa236822013-04-24 18:07:26 -07001216 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001217 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001218 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001219 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001220
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001221 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1222 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001223 return false;
1224 }
1225
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001226 /* Bail out if we are processing only secured video layers
1227 * and we dont have any */
1228 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001229 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001230 return false;
1231 }
1232
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001233 if(mCurrentFrame.fbCount)
1234 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001235
Raj Kamal389d6e32014-08-04 14:43:24 +05301236 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001237 adjustForSourceSplit(ctx, list);
1238 }
1239
1240 if(!postHeuristicsHandling(ctx, list)) {
1241 ALOGD_IF(isDebug(), "post heuristic handling failed");
1242 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001243 return false;
1244 }
1245
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001246 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1247 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001248 return true;
1249}
1250
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001251/* Checks for conditions where YUV layers cannot be bypassed */
1252bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001253 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001254 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001255 return false;
1256 }
1257
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001258 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001259 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1260 return false;
1261 }
1262
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001263 if(isSecuring(ctx, layer)) {
1264 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1265 return false;
1266 }
1267
Saurabh Shah4fdde762013-04-30 18:47:33 -07001268 if(!isValidDimension(ctx, layer)) {
1269 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1270 __FUNCTION__);
1271 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001272 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001273
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001274 if(layer->planeAlpha < 0xFF) {
1275 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1276 in video only mode",
1277 __FUNCTION__);
1278 return false;
1279 }
1280
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001281 return true;
1282}
1283
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301284/* starts at fromIndex and check for each layer to find
1285 * if it it has overlapping with any Updating layer above it in zorder
1286 * till the end of the batch. returns true if it finds any intersection */
1287bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1288 int fromIndex, int toIndex) {
1289 for(int i = fromIndex; i < toIndex; i++) {
1290 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1291 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1292 return false;
1293 }
1294 }
1295 }
1296 return true;
1297}
1298
1299/* Checks if given layer at targetLayerIndex has any
1300 * intersection with all the updating layers in beween
1301 * fromIndex and toIndex. Returns true if it finds intersectiion */
1302bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1303 int fromIndex, int toIndex, int targetLayerIndex) {
1304 for(int i = fromIndex; i <= toIndex; i++) {
1305 if(!mCurrentFrame.isFBComposed[i]) {
1306 if(areLayersIntersecting(&list->hwLayers[i],
1307 &list->hwLayers[targetLayerIndex])) {
1308 return true;
1309 }
1310 }
1311 }
1312 return false;
1313}
1314
1315int MDPComp::getBatch(hwc_display_contents_1_t* list,
1316 int& maxBatchStart, int& maxBatchEnd,
1317 int& maxBatchCount) {
1318 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301319 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001320 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301321 while (i < mCurrentFrame.layerCount) {
1322 int batchCount = 0;
1323 int batchStart = i;
1324 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001325 /* Adjust batch Z order with the dropped layers so far */
1326 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301327 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301328 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301329 while(i < mCurrentFrame.layerCount) {
1330 if(!mCurrentFrame.isFBComposed[i]) {
1331 if(!batchCount) {
1332 i++;
1333 break;
1334 }
1335 updatingLayersAbove++;
1336 i++;
1337 continue;
1338 } else {
1339 if(mCurrentFrame.drop[i]) {
1340 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001341 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301342 continue;
1343 } else if(updatingLayersAbove <= 0) {
1344 batchCount++;
1345 batchEnd = i;
1346 i++;
1347 continue;
1348 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1349
1350 // We have a valid updating layer already. If layer-i not
1351 // have overlapping with all updating layers in between
1352 // batch-start and i, then we can add layer i to batch.
1353 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1354 batchCount++;
1355 batchEnd = i;
1356 i++;
1357 continue;
1358 } else if(canPushBatchToTop(list, batchStart, i)) {
1359 //If All the non-updating layers with in this batch
1360 //does not have intersection with the updating layers
1361 //above in z-order, then we can safely move the batch to
1362 //higher z-order. Increment fbZ as it is moving up.
1363 if( firstZReverseIndex < 0) {
1364 firstZReverseIndex = i;
1365 }
1366 batchCount++;
1367 batchEnd = i;
1368 fbZ += updatingLayersAbove;
1369 i++;
1370 updatingLayersAbove = 0;
1371 continue;
1372 } else {
1373 //both failed.start the loop again from here.
1374 if(firstZReverseIndex >= 0) {
1375 i = firstZReverseIndex;
1376 }
1377 break;
1378 }
1379 }
1380 }
1381 }
1382 if(batchCount > maxBatchCount) {
1383 maxBatchCount = batchCount;
1384 maxBatchStart = batchStart;
1385 maxBatchEnd = batchEnd;
1386 fbZOrder = fbZ;
1387 }
1388 }
1389 return fbZOrder;
1390}
1391
1392bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1393 hwc_display_contents_1_t* list) {
1394 /* Idea is to keep as many non-updating(cached) layers in FB and
1395 * send rest of them through MDP. This is done in 2 steps.
1396 * 1. Find the maximum contiguous batch of non-updating layers.
1397 * 2. See if we can improve this batch size for caching by adding
1398 * opaque layers around the batch, if they don't have
1399 * any overlapping with the updating layers in between.
1400 * NEVER mark an updating layer for caching.
1401 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001402
1403 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001404 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001405 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301406 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001407
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001408 /* Nothing is cached. No batching needed */
1409 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001410 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001411 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001412
1413 /* No MDP comp layers, try to use other comp modes */
1414 if(mCurrentFrame.mdpCount == 0) {
1415 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001416 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001417
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301418 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001419
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301420 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001421 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001422 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001423 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301424 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001425 if(!mCurrentFrame.drop[i]){
1426 //If an unsupported layer is being attempted to
1427 //be pulled out we should fail
1428 if(not isSupportedForMDPComp(ctx, layer)) {
1429 return false;
1430 }
1431 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001432 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001433 }
1434 }
1435
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301436 // update the frame data
1437 mCurrentFrame.fbZ = fbZ;
1438 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001439 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001440 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001441
1442 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301443 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001444
1445 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001446}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001447
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001448void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001449 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001450 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001451 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001452
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001453 for(int i = 0; i < numAppLayers; i++) {
1454 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001455 if(!mCurrentFrame.drop[i])
1456 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001457 mCurrentFrame.isFBComposed[i] = true;
1458 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001459 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001460 }
1461 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001462
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001463 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001464 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1465 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001466
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001467 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1468 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1469 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001470}
1471
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001472void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1473 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001474 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1475 for(int index = 0;index < nYuvCount; index++){
1476 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1477 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1478
1479 if(!isYUVDoable(ctx, layer)) {
1480 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1481 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1482 mCurrentFrame.fbCount++;
1483 }
1484 } else {
1485 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001486 private_handle_t *hnd = (private_handle_t *)layer->handle;
1487 if(!secureOnly || isSecureBuffer(hnd)) {
1488 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1489 mCurrentFrame.fbCount--;
1490 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001491 }
1492 }
1493 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001494
1495 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001496 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1497 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001498 mCurrentFrame.fbCount);
1499}
1500
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001501hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1502 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001503 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001504
1505 /* Update only the region of FB needed for composition */
1506 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1507 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1508 hwc_layer_1_t* layer = &list->hwLayers[i];
1509 hwc_rect_t dst = layer->displayFrame;
1510 fbRect = getUnion(fbRect, dst);
1511 }
1512 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001513 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001514 return fbRect;
1515}
1516
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001517bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1518 hwc_display_contents_1_t* list) {
1519
1520 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001521 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001522 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1523 return false;
1524 }
1525
1526 //Limitations checks
1527 if(!hwLimitationsCheck(ctx, list)) {
1528 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1529 return false;
1530 }
1531
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001532 //Configure framebuffer first if applicable
1533 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001534 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001535 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1536 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001537 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1538 __FUNCTION__);
1539 return false;
1540 }
1541 }
1542
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001543 mCurrentFrame.map();
1544
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001545 if(!allocLayerPipes(ctx, list)) {
1546 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001547 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001548 }
1549
1550 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001551 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001552 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001553 int mdpIndex = mCurrentFrame.layerToMDP[index];
1554 hwc_layer_1_t* layer = &list->hwLayers[index];
1555
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301556 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1557 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1558 mdpNextZOrder++;
1559 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001560 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1561 cur_pipe->zOrder = mdpNextZOrder++;
1562
radhakrishnac9a67412013-09-25 17:40:42 +05301563 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301564 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301565 if(configure4k2kYuv(ctx, layer,
1566 mCurrentFrame.mdpToLayer[mdpIndex])
1567 != 0 ){
1568 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1569 for layer %d",__FUNCTION__, index);
1570 return false;
1571 }
1572 else{
1573 mdpNextZOrder++;
1574 }
1575 continue;
1576 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1578 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301579 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001580 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001581 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001582 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583 }
1584
Saurabh Shaha36be922013-12-16 18:18:39 -08001585 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1586 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1587 ,__FUNCTION__, mDpy);
1588 return false;
1589 }
1590
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001591 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001592 return true;
1593}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001594
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001595bool MDPComp::resourceCheck(hwc_context_t* ctx,
1596 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001597 const bool fbUsed = mCurrentFrame.fbCount;
1598 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1599 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1600 return false;
1601 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001602 // Init rotCount to number of rotate sessions used by other displays
1603 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1604 // Count the number of rotator sessions required for current display
1605 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1606 if(!mCurrentFrame.isFBComposed[index]) {
1607 hwc_layer_1_t* layer = &list->hwLayers[index];
1608 private_handle_t *hnd = (private_handle_t *)layer->handle;
1609 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1610 rotCount++;
1611 }
1612 }
1613 }
1614 // if number of layers to rotate exceeds max rotator sessions, bail out.
1615 if(rotCount > RotMgr::MAX_ROT_SESS) {
1616 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1617 __FUNCTION__, mDpy);
1618 return false;
1619 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001620 return true;
1621}
1622
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301623bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1624 hwc_display_contents_1_t* list) {
1625
1626 //A-family hw limitation:
1627 //If a layer need alpha scaling, MDP can not support.
1628 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1629 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1630 if(!mCurrentFrame.isFBComposed[i] &&
1631 isAlphaScaled( &list->hwLayers[i])) {
1632 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1633 return false;
1634 }
1635 }
1636 }
1637
1638 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1639 //If multiple layers requires downscaling and also they are overlapping
1640 //fall back to GPU since MDSS can not handle it.
1641 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1642 qdutils::MDPVersion::getInstance().is8x26()) {
1643 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1644 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1645 if(!mCurrentFrame.isFBComposed[i] &&
1646 isDownscaleRequired(botLayer)) {
1647 //if layer-i is marked for MDP and needs downscaling
1648 //check if any MDP layer on top of i & overlaps with layer-i
1649 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1650 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1651 if(!mCurrentFrame.isFBComposed[j] &&
1652 isDownscaleRequired(topLayer)) {
1653 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1654 topLayer->displayFrame);
1655 if(isValidRect(r))
1656 return false;
1657 }
1658 }
1659 }
1660 }
1661 }
1662 return true;
1663}
1664
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001665int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001666 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001667 char property[PROPERTY_VALUE_MAX];
1668
Raj Kamal4393eaa2014-06-06 13:45:20 +05301669 if(!ctx || !list) {
1670 ALOGE("%s: Invalid context or list",__FUNCTION__);
1671 mCachedFrame.reset();
1672 return -1;
1673 }
1674
1675 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1676
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001677 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1678 int currentFlags = atoi(property);
1679 if(currentFlags != sSimulationFlags) {
1680 sSimulationFlags = currentFlags;
1681 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1682 sSimulationFlags, sSimulationFlags);
1683 }
1684 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001685 // reset PTOR
1686 if(!mDpy)
1687 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001688
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301689 //Do not cache the information for next draw cycle.
1690 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1691 ALOGI("%s: Unsupported layer count for mdp composition",
1692 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001693 mCachedFrame.reset();
1694 return -1;
1695 }
1696
Saurabh Shahb39f8152013-08-22 10:21:44 -07001697 //reset old data
1698 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001699 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1700 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301701
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001702 // Detect the start of animation and fall back to GPU only once to cache
1703 // all the layers in FB and display FB content untill animation completes.
1704 if(ctx->listStats[mDpy].isDisplayAnimating) {
1705 mCurrentFrame.needsRedraw = false;
1706 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1707 mCurrentFrame.needsRedraw = true;
1708 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1709 }
1710 setMDPCompLayerFlags(ctx, list);
1711 mCachedFrame.updateCounts(mCurrentFrame);
1712 ret = -1;
1713 return ret;
1714 } else {
1715 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1716 }
1717
Saurabh Shahb39f8152013-08-22 10:21:44 -07001718 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001719 if(isFrameDoable(ctx)) {
1720 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001721
Raj Kamal4393eaa2014-06-06 13:45:20 +05301722 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1723 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001724 setMDPCompLayerFlags(ctx, list);
1725 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001726 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001727 reset(ctx);
1728 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1729 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001730 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001731 }
1732 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001733 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1734 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001735 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001736 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001737
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001738 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001739 ALOGD("GEOMETRY change: %d",
1740 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001741 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001742 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001743 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001744 }
1745
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001746 mCachedFrame.cacheAll(list);
1747 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001748 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001749}
1750
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001751bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301752
1753 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301754 int mdpIndex = mCurrentFrame.layerToMDP[index];
1755 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1756 info.pipeInfo = new MdpYUVPipeInfo;
1757 info.rot = NULL;
1758 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301759
1760 pipe_info.lIndex = ovutils::OV_INVALID;
1761 pipe_info.rIndex = ovutils::OV_INVALID;
1762
Saurabh Shahc62f3982014-03-05 14:28:26 -08001763 Overlay::PipeSpecs pipeSpecs;
1764 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1765 pipeSpecs.needsScaling = true;
1766 pipeSpecs.dpy = mDpy;
1767 pipeSpecs.fb = false;
1768
1769 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301770 if(pipe_info.lIndex == ovutils::OV_INVALID){
1771 bRet = false;
1772 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1773 __FUNCTION__);
1774 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001775 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301776 if(pipe_info.rIndex == ovutils::OV_INVALID){
1777 bRet = false;
1778 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1779 __FUNCTION__);
1780 }
1781 return bRet;
1782}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001783
1784int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1785 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001786 if (ctx->mPtorInfo.isActive()) {
1787 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001788 if (fd < 0) {
1789 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001790 }
1791 }
1792 return fd;
1793}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001794//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001795
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001796void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301797 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001798 //If 4k2k Yuv layer split is possible, and if
1799 //fbz is above 4k2k layer, increment fb zorder by 1
1800 //as we split 4k2k layer and increment zorder for right half
1801 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001802 if(!ctx)
1803 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001804 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301805 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1806 index++) {
1807 if(!mCurrentFrame.isFBComposed[index]) {
1808 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1809 mdpNextZOrder++;
1810 }
1811 mdpNextZOrder++;
1812 hwc_layer_1_t* layer = &list->hwLayers[index];
1813 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301814 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301815 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1816 mCurrentFrame.fbZ += 1;
1817 mdpNextZOrder++;
1818 //As we split 4kx2k yuv layer and program to 2 VG pipes
1819 //(if available) increase mdpcount by 1.
1820 mCurrentFrame.mdpCount++;
1821 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001822 }
1823 }
1824 }
radhakrishnac9a67412013-09-25 17:40:42 +05301825}
1826
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001827/*
1828 * Configures pipe(s) for MDP composition
1829 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001830int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001831 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001832 MdpPipeInfoNonSplit& mdp_info =
1833 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001834 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1835 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1836 eIsFg isFg = IS_FG_OFF;
1837 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001838
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001839 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1840 __FUNCTION__, layer, zOrder, dest);
1841
Saurabh Shah88e4d272013-09-03 13:31:29 -07001842 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001843 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001844}
1845
Saurabh Shah88e4d272013-09-03 13:31:29 -07001846bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001847 hwc_display_contents_1_t* list) {
1848 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001849
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001850 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001851
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001852 hwc_layer_1_t* layer = &list->hwLayers[index];
1853 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301854 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001855 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301856 continue;
1857 }
1858 }
1859
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001860 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001861 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001862 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001863 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001864 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001865
Saurabh Shahc62f3982014-03-05 14:28:26 -08001866 Overlay::PipeSpecs pipeSpecs;
1867 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1868 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1869 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1870 (qdutils::MDPVersion::getInstance().is8x26() and
1871 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1872 pipeSpecs.dpy = mDpy;
1873 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001874 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001875
Saurabh Shahc62f3982014-03-05 14:28:26 -08001876 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1877
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001878 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001879 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001880 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001881 }
1882 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001883 return true;
1884}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001885
radhakrishnac9a67412013-09-25 17:40:42 +05301886int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1887 PipeLayerPair& PipeLayerPair) {
1888 MdpYUVPipeInfo& mdp_info =
1889 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1890 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1891 eIsFg isFg = IS_FG_OFF;
1892 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1893 eDest lDest = mdp_info.lIndex;
1894 eDest rDest = mdp_info.rIndex;
1895
1896 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1897 lDest, rDest, &PipeLayerPair.rot);
1898}
1899
Saurabh Shah88e4d272013-09-03 13:31:29 -07001900bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001901
Raj Kamal4393eaa2014-06-06 13:45:20 +05301902 if(!isEnabled() or !mModeOn) {
1903 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301904 return true;
1905 }
1906
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001907 // Set the Handle timeout to true for MDP or MIXED composition.
1908 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1909 sHandleTimeout = true;
1910 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001911
1912 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001913 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001914
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001915 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1916 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001917 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001918 if(mCurrentFrame.isFBComposed[i]) continue;
1919
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001920 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001921 private_handle_t *hnd = (private_handle_t *)layer->handle;
1922 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001923 if (!(layer->flags & HWC_COLOR_FILL)) {
1924 ALOGE("%s handle null", __FUNCTION__);
1925 return false;
1926 }
1927 // No PLAY for Color layer
1928 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1929 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001930 }
1931
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001932 int mdpIndex = mCurrentFrame.layerToMDP[i];
1933
Raj Kamal389d6e32014-08-04 14:43:24 +05301934 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05301935 {
1936 MdpYUVPipeInfo& pipe_info =
1937 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1938 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1939 ovutils::eDest indexL = pipe_info.lIndex;
1940 ovutils::eDest indexR = pipe_info.rIndex;
1941 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301942 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301943 if(rot) {
1944 rot->queueBuffer(fd, offset);
1945 fd = rot->getDstMemId();
1946 offset = rot->getDstOffset();
1947 }
1948 if(indexL != ovutils::OV_INVALID) {
1949 ovutils::eDest destL = (ovutils::eDest)indexL;
1950 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1951 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1952 if (!ov.queueBuffer(fd, offset, destL)) {
1953 ALOGE("%s: queueBuffer failed for display:%d",
1954 __FUNCTION__, mDpy);
1955 return false;
1956 }
1957 }
1958
1959 if(indexR != ovutils::OV_INVALID) {
1960 ovutils::eDest destR = (ovutils::eDest)indexR;
1961 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1962 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1963 if (!ov.queueBuffer(fd, offset, destR)) {
1964 ALOGE("%s: queueBuffer failed for display:%d",
1965 __FUNCTION__, mDpy);
1966 return false;
1967 }
1968 }
1969 }
1970 else{
1971 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001972 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301973 ovutils::eDest dest = pipe_info.index;
1974 if(dest == ovutils::OV_INVALID) {
1975 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001976 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301977 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001978
radhakrishnac9a67412013-09-25 17:40:42 +05301979 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1980 continue;
1981 }
1982
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001983 int fd = hnd->fd;
1984 uint32_t offset = (uint32_t)hnd->offset;
1985 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1986 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001987 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001988 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001989 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001990 }
1991
radhakrishnac9a67412013-09-25 17:40:42 +05301992 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1993 using pipe: %d", __FUNCTION__, layer,
1994 hnd, dest );
1995
radhakrishnac9a67412013-09-25 17:40:42 +05301996 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1997 if(rot) {
1998 if(!rot->queueBuffer(fd, offset))
1999 return false;
2000 fd = rot->getDstMemId();
2001 offset = rot->getDstOffset();
2002 }
2003
2004 if (!ov.queueBuffer(fd, offset, dest)) {
2005 ALOGE("%s: queueBuffer failed for display:%d ",
2006 __FUNCTION__, mDpy);
2007 return false;
2008 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002009 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002010
2011 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002012 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002013 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002014}
2015
Saurabh Shah88e4d272013-09-03 13:31:29 -07002016//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002017
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002018void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302019 hwc_display_contents_1_t* list){
2020 //if 4kx2k yuv layer is totally present in either in left half
2021 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302022 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302023 if(mCurrentFrame.fbZ >= 0) {
2024 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2025 index++) {
2026 if(!mCurrentFrame.isFBComposed[index]) {
2027 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2028 mdpNextZOrder++;
2029 }
2030 mdpNextZOrder++;
2031 hwc_layer_1_t* layer = &list->hwLayers[index];
2032 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302033 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302034 hwc_rect_t dst = layer->displayFrame;
2035 if((dst.left > lSplit) || (dst.right < lSplit)) {
2036 mCurrentFrame.mdpCount += 1;
2037 }
2038 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2039 mCurrentFrame.fbZ += 1;
2040 mdpNextZOrder++;
2041 }
2042 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002043 }
radhakrishnac9a67412013-09-25 17:40:42 +05302044 }
2045}
2046
Saurabh Shah88e4d272013-09-03 13:31:29 -07002047bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002048 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002049
Saurabh Shahc62f3982014-03-05 14:28:26 -08002050 const int lSplit = getLeftSplit(ctx, mDpy);
2051 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002052 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002053 pipe_info.lIndex = ovutils::OV_INVALID;
2054 pipe_info.rIndex = ovutils::OV_INVALID;
2055
Saurabh Shahc62f3982014-03-05 14:28:26 -08002056 Overlay::PipeSpecs pipeSpecs;
2057 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2058 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2059 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2060 pipeSpecs.dpy = mDpy;
2061 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2062 pipeSpecs.fb = false;
2063
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002064 // Acquire pipe only for the updating half
2065 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2066 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2067
2068 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002069 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002070 if(pipe_info.lIndex == ovutils::OV_INVALID)
2071 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002072 }
2073
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002074 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002075 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2076 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002077 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002078 return false;
2079 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002080
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002081 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002082}
2083
Saurabh Shah88e4d272013-09-03 13:31:29 -07002084bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002085 hwc_display_contents_1_t* list) {
2086 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002087
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002088 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002089
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002090 hwc_layer_1_t* layer = &list->hwLayers[index];
2091 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302092 hwc_rect_t dst = layer->displayFrame;
2093 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302094 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302095 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002096 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302097 continue;
2098 }
2099 }
2100 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002101 int mdpIndex = mCurrentFrame.layerToMDP[index];
2102 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002103 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002104 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002105 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002106
Saurabh Shahc62f3982014-03-05 14:28:26 -08002107 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2108 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2109 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002110 return false;
2111 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002112 }
2113 return true;
2114}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002115
radhakrishnac9a67412013-09-25 17:40:42 +05302116int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2117 PipeLayerPair& PipeLayerPair) {
2118 const int lSplit = getLeftSplit(ctx, mDpy);
2119 hwc_rect_t dst = layer->displayFrame;
2120 if((dst.left > lSplit)||(dst.right < lSplit)){
2121 MdpYUVPipeInfo& mdp_info =
2122 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2123 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2124 eIsFg isFg = IS_FG_OFF;
2125 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2126 eDest lDest = mdp_info.lIndex;
2127 eDest rDest = mdp_info.rIndex;
2128
2129 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2130 lDest, rDest, &PipeLayerPair.rot);
2131 }
2132 else{
2133 return configure(ctx, layer, PipeLayerPair);
2134 }
2135}
2136
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002137/*
2138 * Configures pipe(s) for MDP composition
2139 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002140int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002141 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002142 MdpPipeInfoSplit& mdp_info =
2143 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002144 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2145 eIsFg isFg = IS_FG_OFF;
2146 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2147 eDest lDest = mdp_info.lIndex;
2148 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002149
2150 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2151 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2152
Saurabh Shah88e4d272013-09-03 13:31:29 -07002153 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002154 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002155}
2156
Saurabh Shah88e4d272013-09-03 13:31:29 -07002157bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002158
Raj Kamal4393eaa2014-06-06 13:45:20 +05302159 if(!isEnabled() or !mModeOn) {
2160 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302161 return true;
2162 }
2163
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002164 // Set the Handle timeout to true for MDP or MIXED composition.
2165 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2166 sHandleTimeout = true;
2167 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002168
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002169 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002170 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002171
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002172 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2173 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002174 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002175 if(mCurrentFrame.isFBComposed[i]) continue;
2176
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002177 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002178 private_handle_t *hnd = (private_handle_t *)layer->handle;
2179 if(!hnd) {
2180 ALOGE("%s handle null", __FUNCTION__);
2181 return false;
2182 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002183
2184 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2185 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002186 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002187
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002188 int mdpIndex = mCurrentFrame.layerToMDP[i];
2189
Raj Kamal389d6e32014-08-04 14:43:24 +05302190 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302191 {
2192 MdpYUVPipeInfo& pipe_info =
2193 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2194 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2195 ovutils::eDest indexL = pipe_info.lIndex;
2196 ovutils::eDest indexR = pipe_info.rIndex;
2197 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302198 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302199 if(rot) {
2200 rot->queueBuffer(fd, offset);
2201 fd = rot->getDstMemId();
2202 offset = rot->getDstOffset();
2203 }
2204 if(indexL != ovutils::OV_INVALID) {
2205 ovutils::eDest destL = (ovutils::eDest)indexL;
2206 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2207 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2208 if (!ov.queueBuffer(fd, offset, destL)) {
2209 ALOGE("%s: queueBuffer failed for display:%d",
2210 __FUNCTION__, mDpy);
2211 return false;
2212 }
2213 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002214
radhakrishnac9a67412013-09-25 17:40:42 +05302215 if(indexR != ovutils::OV_INVALID) {
2216 ovutils::eDest destR = (ovutils::eDest)indexR;
2217 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2218 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2219 if (!ov.queueBuffer(fd, offset, destR)) {
2220 ALOGE("%s: queueBuffer failed for display:%d",
2221 __FUNCTION__, mDpy);
2222 return false;
2223 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002224 }
2225 }
radhakrishnac9a67412013-09-25 17:40:42 +05302226 else{
2227 MdpPipeInfoSplit& pipe_info =
2228 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2229 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002230
radhakrishnac9a67412013-09-25 17:40:42 +05302231 ovutils::eDest indexL = pipe_info.lIndex;
2232 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002233
radhakrishnac9a67412013-09-25 17:40:42 +05302234 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002235 uint32_t offset = (uint32_t)hnd->offset;
2236 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2237 if (!mDpy && (index != -1)) {
2238 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2239 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002240 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002241 }
radhakrishnac9a67412013-09-25 17:40:42 +05302242
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002243 if(ctx->mAD->draw(ctx, fd, offset)) {
2244 fd = ctx->mAD->getDstFd();
2245 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002246 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002247
radhakrishnac9a67412013-09-25 17:40:42 +05302248 if(rot) {
2249 rot->queueBuffer(fd, offset);
2250 fd = rot->getDstMemId();
2251 offset = rot->getDstOffset();
2252 }
2253
2254 //************* play left mixer **********
2255 if(indexL != ovutils::OV_INVALID) {
2256 ovutils::eDest destL = (ovutils::eDest)indexL;
2257 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2258 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2259 if (!ov.queueBuffer(fd, offset, destL)) {
2260 ALOGE("%s: queueBuffer failed for left mixer",
2261 __FUNCTION__);
2262 return false;
2263 }
2264 }
2265
2266 //************* play right mixer **********
2267 if(indexR != ovutils::OV_INVALID) {
2268 ovutils::eDest destR = (ovutils::eDest)indexR;
2269 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2270 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2271 if (!ov.queueBuffer(fd, offset, destR)) {
2272 ALOGE("%s: queueBuffer failed for right mixer",
2273 __FUNCTION__);
2274 return false;
2275 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002276 }
2277 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002278
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002279 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2280 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002281
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002282 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002283}
Saurabh Shahab47c692014-02-12 18:45:57 -08002284
2285//================MDPCompSrcSplit==============================================
2286bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002287 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002288 private_handle_t *hnd = (private_handle_t *)layer->handle;
2289 hwc_rect_t dst = layer->displayFrame;
2290 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2291 pipe_info.lIndex = ovutils::OV_INVALID;
2292 pipe_info.rIndex = ovutils::OV_INVALID;
2293
2294 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2295 //should have a higher priority than the right one. Pipe priorities are
2296 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002297
Saurabh Shahc62f3982014-03-05 14:28:26 -08002298 Overlay::PipeSpecs pipeSpecs;
2299 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2300 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2301 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2302 pipeSpecs.dpy = mDpy;
2303 pipeSpecs.fb = false;
2304
Saurabh Shahab47c692014-02-12 18:45:57 -08002305 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002306 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002307 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002308 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002309 }
2310
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002311 /* Use 2 pipes IF
2312 a) Layer's crop width is > 2048 or
2313 b) Layer's dest width > 2048 or
2314 c) On primary, driver has indicated with caps to split always. This is
2315 based on an empirically derived value of panel height. Applied only
2316 if the layer's width is > mixer's width
2317 */
2318
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302319 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002320 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302321 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002322 int lSplit = getLeftSplit(ctx, mDpy);
2323 int dstWidth = dst.right - dst.left;
2324 int cropWidth = crop.right - crop.left;
2325
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002326 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2327 //pipe line length, we are still using 2 pipes. This is fine just because
2328 //this is source split where destination doesn't matter. Evaluate later to
2329 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302330 if(dstWidth > mdpHw.getMaxMixerWidth() or
2331 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002332 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002333 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002334 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002335 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002336 }
2337
2338 // Return values
2339 // 1 Left pipe is higher priority, do nothing.
2340 // 0 Pipes of same priority.
2341 //-1 Right pipe is of higher priority, needs swap.
2342 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2343 pipe_info.rIndex) == -1) {
2344 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002345 }
2346 }
2347
2348 return true;
2349}
2350
Saurabh Shahab47c692014-02-12 18:45:57 -08002351int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2352 PipeLayerPair& PipeLayerPair) {
2353 private_handle_t *hnd = (private_handle_t *)layer->handle;
2354 if(!hnd) {
2355 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2356 return -1;
2357 }
2358 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2359 MdpPipeInfoSplit& mdp_info =
2360 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2361 Rotator **rot = &PipeLayerPair.rot;
2362 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2363 eIsFg isFg = IS_FG_OFF;
2364 eDest lDest = mdp_info.lIndex;
2365 eDest rDest = mdp_info.rIndex;
2366 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2367 hwc_rect_t dst = layer->displayFrame;
2368 int transform = layer->transform;
2369 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002370 int rotFlags = ROT_FLAGS_NONE;
2371 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2372 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2373
2374 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2375 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2376
2377 // Handle R/B swap
2378 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2379 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2380 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2381 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2382 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2383 }
2384
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002385 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002386 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002387 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002388
2389 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2390 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002391 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002392 }
2393
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002394 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002395 (*rot) = ctx->mRotMgr->getNext();
2396 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002397 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002398 //If the video is using a single pipe, enable BWC
2399 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002400 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002401 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002402 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002403 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002404 ALOGE("%s: configRotator failed!", __FUNCTION__);
2405 return -1;
2406 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002407 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002408 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002409 }
2410
2411 //If 2 pipes being used, divide layer into half, crop and dst
2412 hwc_rect_t cropL = crop;
2413 hwc_rect_t cropR = crop;
2414 hwc_rect_t dstL = dst;
2415 hwc_rect_t dstR = dst;
2416 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2417 cropL.right = (crop.right + crop.left) / 2;
2418 cropR.left = cropL.right;
2419 sanitizeSourceCrop(cropL, cropR, hnd);
2420
2421 //Swap crops on H flip since 2 pipes are being used
2422 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2423 hwc_rect_t tmp = cropL;
2424 cropL = cropR;
2425 cropR = tmp;
2426 }
2427
2428 dstL.right = (dst.right + dst.left) / 2;
2429 dstR.left = dstL.right;
2430 }
2431
2432 //For the mdp, since either we are pre-rotating or MDP does flips
2433 orient = OVERLAY_TRANSFORM_0;
2434 transform = 0;
2435
2436 //configure left pipe
2437 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002438 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002439 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2440 (ovutils::eBlending) getBlending(layer->blending));
2441
2442 if(configMdp(ctx->mOverlay, pargL, orient,
2443 cropL, dstL, metadata, lDest) < 0) {
2444 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2445 return -1;
2446 }
2447 }
2448
2449 //configure right pipe
2450 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002451 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002452 static_cast<eRotFlags>(rotFlags),
2453 layer->planeAlpha,
2454 (ovutils::eBlending) getBlending(layer->blending));
2455 if(configMdp(ctx->mOverlay, pargR, orient,
2456 cropR, dstR, metadata, rDest) < 0) {
2457 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2458 return -1;
2459 }
2460 }
2461
2462 return 0;
2463}
2464
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002465}; //namespace
2466