blob: 9073fa06ab532f13b5d7358ac19b618d6673b2f8 [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 Shahf7fad542014-08-14 10:11:36 -0700241 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700242 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800243}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800244
Saurabh Shahaa236822013-04-24 18:07:26 -0700245void MDPComp::FrameInfo::reset(const int& numLayers) {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700246 for(int i = 0; i < MAX_PIPES_PER_MIXER; i++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800247 if(mdpToLayer[i].pipeInfo) {
248 delete mdpToLayer[i].pipeInfo;
249 mdpToLayer[i].pipeInfo = NULL;
250 //We dont own the rotator
251 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800252 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800253 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800254
255 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
256 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700257 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800258
Saurabh Shahaa236822013-04-24 18:07:26 -0700259 layerCount = numLayers;
260 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700262 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800263 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264}
265
Saurabh Shahaa236822013-04-24 18:07:26 -0700266void MDPComp::FrameInfo::map() {
267 // populate layer and MDP maps
268 int mdpIdx = 0;
269 for(int idx = 0; idx < layerCount; idx++) {
270 if(!isFBComposed[idx]) {
271 mdpToLayer[mdpIdx].listIndex = idx;
272 layerToMDP[idx] = mdpIdx++;
273 }
274 }
275}
276
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800277MDPComp::LayerCache::LayerCache() {
278 reset();
279}
280
281void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700282 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530283 memset(&isFBComposed, true, sizeof(isFBComposed));
284 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800285 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700286}
287
288void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530289 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700290 for(int i = 0; i < numAppLayers; i++) {
291 hnd[i] = list->hwLayers[i].handle;
292 }
293}
294
295void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700296 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530297 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
298 memcpy(&drop, &curFrame.drop, sizeof(drop));
299}
300
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800301bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
302 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530303 if(layerCount != curFrame.layerCount)
304 return false;
305 for(int i = 0; i < curFrame.layerCount; i++) {
306 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
307 (curFrame.drop[i] != drop[i])) {
308 return false;
309 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800310 if(curFrame.isFBComposed[i] &&
311 (hnd[i] != list->hwLayers[i].handle)){
312 return false;
313 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530314 }
315 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316}
317
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700318bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
319 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800320 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700321 (not isValidDimension(ctx,layer))
322 //More conditions here, SKIP, sRGB+Blend etc
323 ) {
324 return false;
325 }
326 return true;
327}
328
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530329bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800330 private_handle_t *hnd = (private_handle_t *)layer->handle;
331
332 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700333 if (layer->flags & HWC_COLOR_FILL) {
334 // Color layer
335 return true;
336 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800337 ALOGE("%s: layer handle is NULL", __FUNCTION__);
338 return false;
339 }
340
Naseer Ahmede850a802013-09-06 13:12:52 -0400341 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400342 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400343 return false;
344
Saurabh Shah62e1d732013-09-17 10:44:05 -0700345 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700346 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700347 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700348 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
349 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700350 int dst_w = dst.right - dst.left;
351 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800352 float w_scale = ((float)crop_w / (float)dst_w);
353 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530354 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700355
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800356 /* Workaround for MDP HW limitation in DSI command mode panels where
357 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
358 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530359 * There also is a HW limilation in MDP, minimum block size is 2x2
360 * Fallback to GPU if height is less than 2.
361 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800362 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800363 return false;
364
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800365 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530366 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800367 const float w_dscale = w_scale;
368 const float h_dscale = h_scale;
369
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800370 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700371
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530372 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700373 /* On targets that doesnt support Decimation (eg.,8x26)
374 * maximum downscale support is overlay pipe downscale.
375 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530376 if(crop_w > mdpHw.getMaxMixerWidth() ||
377 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700378 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800379 return false;
380 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700381 // Decimation on macrotile format layers is not supported.
382 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530383 /* Bail out if
384 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700385 * 2. exceeds maximum downscale limit
386 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530387 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
388 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700389 w_dscale > maxMDPDownscale ||
390 h_dscale > maxMDPDownscale) {
391 return false;
392 }
393 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800394 return false;
395 }
396 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700397 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700398 return false;
399 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700400 }
401
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800402 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530403 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800404 const float w_uscale = 1.0f / w_scale;
405 const float h_uscale = 1.0f / h_scale;
406
407 if(w_uscale > upscale || h_uscale > upscale)
408 return false;
409 }
410
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800411 return true;
412}
413
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800414bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700415 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800416
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800417 if(!isEnabled()) {
418 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700419 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530420 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530421 qdutils::MDPVersion::getInstance().is8x16() ||
422 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800423 ctx->mVideoTransFlag &&
424 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700425 //1 Padding round to shift pipes across mixers
426 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
427 __FUNCTION__);
428 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800429 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800430 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800431 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700432 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700433 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530434 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
435 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700437 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700438 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800439}
440
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800441void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
442 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
443 fbRect = getIntersection(fbRect, roi);
444}
445
446/* 1) Identify layers that are not visible or lying outside the updating ROI and
447 * drop them from composition.
448 * 2) If we have a scaling layer which needs cropping against generated
449 * ROI, reset ROI to full resolution. */
450bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
451 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700452 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800453 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800454
455 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800456 if(!isValidRect(visibleRect)) {
457 mCurrentFrame.drop[i] = true;
458 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800459 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800460 }
461
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700462 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700463 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800464 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700466 if(!isValidRect(res)) {
467 mCurrentFrame.drop[i] = true;
468 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800469 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700470 /* Reset frame ROI when any layer which needs scaling also needs ROI
471 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800472 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800473 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700474 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
475 mCurrentFrame.dropCount = 0;
476 return false;
477 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800478
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800479 /* deduct any opaque region from visibleRect */
480 if (layer->blending == HWC_BLENDING_NONE)
481 visibleRect = deductRect(visibleRect, res);
482 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700483 }
484 return true;
485}
486
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800487/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
488 * are updating. If DirtyRegion is applicable, calculate it by accounting all
489 * the changing layer's dirtyRegion. */
490void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
491 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700492 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800493 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700494 return;
495
496 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800497 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
498 (int)ctx->dpyAttr[mDpy].yres};
499
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700500 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800501 hwc_layer_1_t* layer = &list->hwLayers[index];
502 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800503 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700504 hwc_rect_t dst = layer->displayFrame;
505 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800506
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800507#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800508 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700509 {
510 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
511 int x_off = dst.left - src.left;
512 int y_off = dst.top - src.top;
513 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
514 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800515#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800516
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800517 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700518 }
519 }
520
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800521 /* No layer is updating. Still SF wants a refresh.*/
522 if(!isValidRect(roi))
523 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800524
525 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800526 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800527
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528 ctx->listStats[mDpy].lRoi = roi;
529 if(!validateAndApplyROI(ctx, list))
530 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700531
532 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
534 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
535}
536
537void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
538 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
539 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
540
541 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
542 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
543 fbRect = getUnion(l_fbRect, r_fbRect);
544}
545/* 1) Identify layers that are not visible or lying outside BOTH the updating
546 * ROI's and drop them from composition. If a layer is spanning across both
547 * the halves of the screen but needed by only ROI, the non-contributing
548 * half will not be programmed for MDP.
549 * 2) If we have a scaling layer which needs cropping against generated
550 * ROI, reset ROI to full resolution. */
551bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
552 hwc_display_contents_1_t* list) {
553
554 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
555
556 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
557 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
558
559 for(int i = numAppLayers - 1; i >= 0; i--){
560 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
561 {
562 mCurrentFrame.drop[i] = true;
563 mCurrentFrame.dropCount++;
564 continue;
565 }
566
567 const hwc_layer_1_t* layer = &list->hwLayers[i];
568 hwc_rect_t dstRect = layer->displayFrame;
569
570 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
571 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
572 hwc_rect_t res = getUnion(l_res, r_res);
573
574 if(!isValidRect(l_res) && !isValidRect(r_res)) {
575 mCurrentFrame.drop[i] = true;
576 mCurrentFrame.dropCount++;
577 } else {
578 /* Reset frame ROI when any layer which needs scaling also needs ROI
579 * cropping */
580 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
581 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
582 mCurrentFrame.dropCount = 0;
583 return false;
584 }
585
586 if (layer->blending == HWC_BLENDING_NONE) {
587 visibleRectL = deductRect(visibleRectL, l_res);
588 visibleRectR = deductRect(visibleRectR, r_res);
589 }
590 }
591 }
592 return true;
593}
594/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
595 * are updating. If DirtyRegion is applicable, calculate it by accounting all
596 * the changing layer's dirtyRegion. */
597void MDPCompSplit::generateROI(hwc_context_t *ctx,
598 hwc_display_contents_1_t* list) {
599 if(!canPartialUpdate(ctx, list))
600 return;
601
602 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
603 int lSplit = getLeftSplit(ctx, mDpy);
604
605 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
606 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
607
608 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
609 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
610
611 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
612 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
613
614 for(int index = 0; index < numAppLayers; index++ ) {
615 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800616 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800617 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800618 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700619 hwc_rect_t dst = layer->displayFrame;
620 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800621
622#ifdef QCOM_BSP
623 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700624 {
625 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
626 int x_off = dst.left - src.left;
627 int y_off = dst.top - src.top;
628 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
629 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800630#endif
631
632 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
633 if(isValidRect(l_dst))
634 l_roi = getUnion(l_roi, l_dst);
635
636 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
637 if(isValidRect(r_dst))
638 r_roi = getUnion(r_roi, r_dst);
639 }
640 }
641
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700642 /* For panels that cannot accept commands in both the interfaces, we cannot
643 * send two ROI's (for each half). We merge them into single ROI and split
644 * them across lSplit for MDP mixer use. The ROI's will be merged again
645 * finally before udpating the panel in the driver. */
646 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
647 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
648 l_roi = getIntersection(temp_roi, l_frame);
649 r_roi = getIntersection(temp_roi, r_frame);
650 }
651
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800652 /* No layer is updating. Still SF wants a refresh. */
653 if(!isValidRect(l_roi) && !isValidRect(r_roi))
654 return;
655
656 l_roi = getSanitizeROI(l_roi, l_frame);
657 r_roi = getSanitizeROI(r_roi, r_frame);
658
659 ctx->listStats[mDpy].lRoi = l_roi;
660 ctx->listStats[mDpy].rRoi = r_roi;
661
662 if(!validateAndApplyROI(ctx, list))
663 resetROI(ctx, mDpy);
664
665 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
666 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
667 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
668 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
669 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
670 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700671}
672
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800673/* Checks for conditions where all the layers marked for MDP comp cannot be
674 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800675bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800676 hwc_display_contents_1_t* list){
677
Saurabh Shahaa236822013-04-24 18:07:26 -0700678 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800679 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800680
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700681 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700682 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
683 return false;
684 }
685
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800686 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700687 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
688 __FUNCTION__,
689 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800690 return false;
691 }
692
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530693 MDPVersion& mdpHw = MDPVersion::getInstance();
694 if(mDpy > HWC_DISPLAY_PRIMARY &&
695 (priDispW > mdpHw.getMaxMixerWidth()) &&
696 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800697 // Disable MDP comp on Secondary when the primary is highres panel and
698 // the secondary is a normal 1080p, because, MDP comp on secondary under
699 // in such usecase, decimation gets used for downscale and there will be
700 // a quality mismatch when there will be a fallback to GPU comp
701 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
702 __FUNCTION__);
703 return false;
704 }
705
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800706 // check for action safe flag and downscale mode which requires scaling.
707 if(ctx->dpyAttr[mDpy].mActionSafePresent
708 || ctx->dpyAttr[mDpy].mDownScaleMode) {
709 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
710 return false;
711 }
712
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800713 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800714 hwc_layer_1_t* layer = &list->hwLayers[i];
715 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800716
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800717 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700718 if(!canUseRotator(ctx, mDpy)) {
719 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
720 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700721 return false;
722 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800723 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530724
725 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
726 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700727 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530728 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
729 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
730 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800731 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700732
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700733 if(ctx->mAD->isDoable()) {
734 return false;
735 }
736
Saurabh Shahaa236822013-04-24 18:07:26 -0700737 //If all above hard conditions are met we can do full or partial MDP comp.
738 bool ret = false;
739 if(fullMDPComp(ctx, list)) {
740 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700741 } else if(fullMDPCompWithPTOR(ctx, list)) {
742 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700743 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700744 ret = true;
745 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530746
Saurabh Shahaa236822013-04-24 18:07:26 -0700747 return ret;
748}
749
750bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700751
752 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
753 return false;
754
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700755 //Will benefit presentation / secondary-only layer.
756 if((mDpy > HWC_DISPLAY_PRIMARY) &&
757 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
758 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
759 return false;
760 }
761
762 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
763 for(int i = 0; i < numAppLayers; i++) {
764 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700765 if(not mCurrentFrame.drop[i] and
766 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700767 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
768 return false;
769 }
770 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800771
Saurabh Shahaa236822013-04-24 18:07:26 -0700772 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700773 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
774 sizeof(mCurrentFrame.isFBComposed));
775 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
776 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700777
Raj Kamal389d6e32014-08-04 14:43:24 +0530778 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800779 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530780 }
781
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800782 if(!postHeuristicsHandling(ctx, list)) {
783 ALOGD_IF(isDebug(), "post heuristic handling failed");
784 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700785 return false;
786 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700787 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
788 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700789 return true;
790}
791
Sushil Chauhandefd3522014-05-13 18:17:12 -0700792/* Full MDP Composition with Peripheral Tiny Overlap Removal.
793 * MDP bandwidth limitations can be avoided, if the overlap region
794 * covered by the smallest layer at a higher z-order, gets composed
795 * by Copybit on a render buffer, which can be queued to MDP.
796 */
797bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
798 hwc_display_contents_1_t* list) {
799
800 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
801 const int stagesForMDP = min(sMaxPipesPerMixer,
802 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
803
804 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700805 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700806 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
807 return false;
808 }
809
810 // Frame level checks
811 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
812 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
813 isSecurePresent(ctx, mDpy)) {
814 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
815 return false;
816 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700817 // MDP comp checks
818 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700819 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700820 if(not isSupportedForMDPComp(ctx, layer)) {
821 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
822 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700823 }
824 }
825
Sushil Chauhandefd3522014-05-13 18:17:12 -0700826 /* We cannot use this composition mode, if:
827 1. A below layer needs scaling.
828 2. Overlap is not peripheral to display.
829 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700830 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700831 */
832
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700833 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
834 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
835 memset(overlapRect, 0, sizeof(overlapRect));
836 int layerPixelCount, minPixelCount = 0;
837 int numPTORLayersFound = 0;
838 for (int i = numAppLayers-1; (i >= 0 &&
839 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700841 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700842 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700843 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
844 // PTOR layer should be peripheral and cannot have transform
845 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
846 has90Transform(layer)) {
847 continue;
848 }
849 if((3 * (layerPixelCount + minPixelCount)) >
850 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
851 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
852 continue;
853 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700854 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700855 for (int j = i-1; j >= 0; j--) {
856 // Check if the layers below this layer qualifies for PTOR comp
857 hwc_layer_1_t* layer = &list->hwLayers[j];
858 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700859 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700860 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700861 if (isValidRect(getIntersection(dispFrame, disFrame))) {
862 if (has90Transform(layer) || needsScaling(layer)) {
863 found = false;
864 break;
865 }
866 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700867 }
868 }
869 // Store the minLayer Index
870 if(found) {
871 minLayerIndex[numPTORLayersFound] = i;
872 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
873 minPixelCount += layerPixelCount;
874 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700875 }
876 }
877
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700878 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
879 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
880 __FUNCTION__);
881 // reset second minLayerIndex[1];
882 minLayerIndex[1] = -1;
883 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700884 }
885
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700886 // No overlap layers
887 if (!numPTORLayersFound)
888 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700889
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700890 ctx->mPtorInfo.count = numPTORLayersFound;
891 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
892 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
893 }
894
895 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
896 // reset PTOR
897 ctx->mPtorInfo.count = 0;
898 return false;
899 }
900 // Store the displayFrame and the sourceCrops of the layers
901 hwc_rect_t displayFrame[numAppLayers];
902 hwc_rect_t sourceCrop[numAppLayers];
903 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700904 hwc_layer_1_t* layer = &list->hwLayers[i];
905 displayFrame[i] = layer->displayFrame;
906 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700907 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700908
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700909 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
910 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
911
Xu Yangcda012c2014-07-30 21:57:21 +0800912 // Store the blending mode, planeAlpha, and transform of PTOR layers
913 int32_t blending[numPTORLayersFound];
914 uint8_t planeAlpha[numPTORLayersFound];
915 uint32_t transform[numPTORLayersFound];
916
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700917 for(int j = 0; j < numPTORLayersFound; j++) {
918 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700919
920 // Update src crop of PTOR layer
921 hwc_layer_1_t* layer = &list->hwLayers[index];
922 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
923 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
924 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
925 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
926
927 // Store & update w, h, format of PTOR layer
928 private_handle_t *hnd = (private_handle_t *)layer->handle;
929 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
930 layerWhf[j] = whf;
931 hnd->width = renderBuf->width;
932 hnd->height = renderBuf->height;
933 hnd->format = renderBuf->format;
934
Xu Yangcda012c2014-07-30 21:57:21 +0800935 // Store & update blending mode, planeAlpha and transform of PTOR layer
936 blending[j] = layer->blending;
937 planeAlpha[j] = layer->planeAlpha;
938 transform[j] = layer->transform;
939 layer->blending = HWC_BLENDING_NONE;
940 layer->planeAlpha = 0xFF;
941 layer->transform = 0;
942
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700943 // Remove overlap from crop & displayFrame of below layers
944 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700945 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700946 if(!isValidRect(getIntersection(layer->displayFrame,
947 overlapRect[j]))) {
948 continue;
949 }
950 // Update layer attributes
951 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
952 hwc_rect_t destRect = deductRect(layer->displayFrame,
953 overlapRect[j]);
954 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
955 layer->transform);
956 layer->sourceCropf.left = (float)srcCrop.left;
957 layer->sourceCropf.top = (float)srcCrop.top;
958 layer->sourceCropf.right = (float)srcCrop.right;
959 layer->sourceCropf.bottom = (float)srcCrop.bottom;
960 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700961 }
962
963 mCurrentFrame.mdpCount = numAppLayers;
964 mCurrentFrame.fbCount = 0;
965 mCurrentFrame.fbZ = -1;
966
967 for (int j = 0; j < numAppLayers; j++)
968 mCurrentFrame.isFBComposed[j] = false;
969
970 bool result = postHeuristicsHandling(ctx, list);
971
972 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700973 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700974 hwc_layer_1_t* layer = &list->hwLayers[i];
975 layer->displayFrame = displayFrame[i];
976 layer->sourceCropf.left = (float)sourceCrop[i].left;
977 layer->sourceCropf.top = (float)sourceCrop[i].top;
978 layer->sourceCropf.right = (float)sourceCrop[i].right;
979 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
980 }
981
Xu Yangcda012c2014-07-30 21:57:21 +0800982 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700983 for (int i = 0; i < numPTORLayersFound; i++) {
984 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +0800985 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700986 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
987 hnd->width = layerWhf[i].w;
988 hnd->height = layerWhf[i].h;
989 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +0800990 layer->blending = blending[i];
991 layer->planeAlpha = planeAlpha[i];
992 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700993 }
994
Sushil Chauhandefd3522014-05-13 18:17:12 -0700995 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700996 // reset PTOR
997 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700998 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700999 } else {
1000 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1001 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001002 }
1003
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001004 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1005 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001006 return result;
1007}
1008
Saurabh Shahaa236822013-04-24 18:07:26 -07001009bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1010{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001011 if(!sEnableMixedMode) {
1012 //Mixed mode is disabled. No need to even try caching.
1013 return false;
1014 }
1015
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001016 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001017 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001018 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001019 cacheBasedComp(ctx, list);
1020 } else {
1021 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001022 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001023 }
1024
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001025 return ret;
1026}
1027
1028bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1029 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001030 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1031 return false;
1032
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001033 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001034 mCurrentFrame.reset(numAppLayers);
1035 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001036
1037 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1038 for(int i = 0; i < numAppLayers; i++) {
1039 if(!mCurrentFrame.isFBComposed[i]) {
1040 hwc_layer_1_t* layer = &list->hwLayers[i];
1041 if(not isSupportedForMDPComp(ctx, layer)) {
1042 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1043 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001044 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001045 return false;
1046 }
1047 }
1048 }
1049
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001050 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301051 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001052 if(!ret) {
1053 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001054 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001055 return false;
1056 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001057
1058 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001059
Raj Kamal389d6e32014-08-04 14:43:24 +05301060 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001061 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301062 }
1063
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001064 //Will benefit cases where a video has non-updating background.
1065 if((mDpy > HWC_DISPLAY_PRIMARY) and
1066 (mdpCount > MAX_SEC_LAYERS)) {
1067 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001068 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001069 return false;
1070 }
1071
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001072 if(!postHeuristicsHandling(ctx, list)) {
1073 ALOGD_IF(isDebug(), "post heuristic handling failed");
1074 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001075 return false;
1076 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001077 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1078 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001079
Saurabh Shahaa236822013-04-24 18:07:26 -07001080 return true;
1081}
1082
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001083bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001084 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001085 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1086 return false;
1087
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001088 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001089 return false;
1090 }
1091
Saurabh Shahb772ae32013-11-18 15:40:02 -08001092 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001093 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1094 const int stagesForMDP = min(sMaxPipesPerMixer,
1095 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001096
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001097 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1098 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1099 int lastMDPSupportedIndex = numAppLayers;
1100 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001101
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001102 //Find the minimum MDP batch size
1103 for(int i = 0; i < numAppLayers;i++) {
1104 if(mCurrentFrame.drop[i]) {
1105 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001106 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001107 }
1108 hwc_layer_1_t* layer = &list->hwLayers[i];
1109 if(not isSupportedForMDPComp(ctx, layer)) {
1110 lastMDPSupportedIndex = i;
1111 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1112 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001113 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001114 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001115 }
1116
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001117 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1118 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1119 mCurrentFrame.dropCount);
1120
1121 //Start at a point where the fb batch should at least have 2 layers, for
1122 //this mode to be justified.
1123 while(fbBatchSize < 2) {
1124 ++fbBatchSize;
1125 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001126 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001127
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001128 //If there are no layers for MDP, this mode doesnt make sense.
1129 if(mdpBatchSize < 1) {
1130 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1131 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001132 return false;
1133 }
1134
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001135 mCurrentFrame.reset(numAppLayers);
1136
1137 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1138 while(mdpBatchSize > 0) {
1139 //Mark layers for MDP comp
1140 int mdpBatchLeft = mdpBatchSize;
1141 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1142 if(mCurrentFrame.drop[i]) {
1143 continue;
1144 }
1145 mCurrentFrame.isFBComposed[i] = false;
1146 --mdpBatchLeft;
1147 }
1148
1149 mCurrentFrame.fbZ = mdpBatchSize;
1150 mCurrentFrame.fbCount = fbBatchSize;
1151 mCurrentFrame.mdpCount = mdpBatchSize;
1152
1153 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1154 __FUNCTION__, mdpBatchSize, fbBatchSize,
1155 mCurrentFrame.dropCount);
1156
1157 if(postHeuristicsHandling(ctx, list)) {
1158 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001159 __FUNCTION__);
1160 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1161 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001162 return true;
1163 }
1164
1165 reset(ctx);
1166 --mdpBatchSize;
1167 ++fbBatchSize;
1168 }
1169
1170 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001171}
1172
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001173bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301174 if(mDpy or isSecurePresent(ctx, mDpy) or
1175 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001176 return false;
1177 }
1178 return true;
1179}
1180
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001181bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1182 hwc_display_contents_1_t* list){
1183 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1184 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1185 mDpy ) {
1186 return false;
1187 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001188 if(ctx->listStats[mDpy].secureUI)
1189 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001190 return true;
1191}
1192
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001193bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1194 hwc_display_contents_1_t* list) {
1195 const bool secureOnly = true;
1196 return videoOnlyComp(ctx, list, not secureOnly) or
1197 videoOnlyComp(ctx, list, secureOnly);
1198}
1199
1200bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001201 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001202 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1203 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001204 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001205
Saurabh Shahaa236822013-04-24 18:07:26 -07001206 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001207 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001208 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001209 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001210
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001211 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1212 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001213 return false;
1214 }
1215
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001216 /* Bail out if we are processing only secured video layers
1217 * and we dont have any */
1218 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001219 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001220 return false;
1221 }
1222
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001223 if(mCurrentFrame.fbCount)
1224 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001225
Raj Kamal389d6e32014-08-04 14:43:24 +05301226 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001227 adjustForSourceSplit(ctx, list);
1228 }
1229
1230 if(!postHeuristicsHandling(ctx, list)) {
1231 ALOGD_IF(isDebug(), "post heuristic handling failed");
1232 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001233 return false;
1234 }
1235
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001236 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1237 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001238 return true;
1239}
1240
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001241/* Checks for conditions where YUV layers cannot be bypassed */
1242bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001243 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001244 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001245 return false;
1246 }
1247
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001248 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001249 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1250 return false;
1251 }
1252
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001253 if(isSecuring(ctx, layer)) {
1254 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1255 return false;
1256 }
1257
Saurabh Shah4fdde762013-04-30 18:47:33 -07001258 if(!isValidDimension(ctx, layer)) {
1259 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1260 __FUNCTION__);
1261 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001262 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001263
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001264 if(layer->planeAlpha < 0xFF) {
1265 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1266 in video only mode",
1267 __FUNCTION__);
1268 return false;
1269 }
1270
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001271 return true;
1272}
1273
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301274/* starts at fromIndex and check for each layer to find
1275 * if it it has overlapping with any Updating layer above it in zorder
1276 * till the end of the batch. returns true if it finds any intersection */
1277bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1278 int fromIndex, int toIndex) {
1279 for(int i = fromIndex; i < toIndex; i++) {
1280 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1281 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1282 return false;
1283 }
1284 }
1285 }
1286 return true;
1287}
1288
1289/* Checks if given layer at targetLayerIndex has any
1290 * intersection with all the updating layers in beween
1291 * fromIndex and toIndex. Returns true if it finds intersectiion */
1292bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1293 int fromIndex, int toIndex, int targetLayerIndex) {
1294 for(int i = fromIndex; i <= toIndex; i++) {
1295 if(!mCurrentFrame.isFBComposed[i]) {
1296 if(areLayersIntersecting(&list->hwLayers[i],
1297 &list->hwLayers[targetLayerIndex])) {
1298 return true;
1299 }
1300 }
1301 }
1302 return false;
1303}
1304
1305int MDPComp::getBatch(hwc_display_contents_1_t* list,
1306 int& maxBatchStart, int& maxBatchEnd,
1307 int& maxBatchCount) {
1308 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301309 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001310 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301311 while (i < mCurrentFrame.layerCount) {
1312 int batchCount = 0;
1313 int batchStart = i;
1314 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001315 /* Adjust batch Z order with the dropped layers so far */
1316 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301317 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301318 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301319 while(i < mCurrentFrame.layerCount) {
1320 if(!mCurrentFrame.isFBComposed[i]) {
1321 if(!batchCount) {
1322 i++;
1323 break;
1324 }
1325 updatingLayersAbove++;
1326 i++;
1327 continue;
1328 } else {
1329 if(mCurrentFrame.drop[i]) {
1330 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001331 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301332 continue;
1333 } else if(updatingLayersAbove <= 0) {
1334 batchCount++;
1335 batchEnd = i;
1336 i++;
1337 continue;
1338 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1339
1340 // We have a valid updating layer already. If layer-i not
1341 // have overlapping with all updating layers in between
1342 // batch-start and i, then we can add layer i to batch.
1343 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1344 batchCount++;
1345 batchEnd = i;
1346 i++;
1347 continue;
1348 } else if(canPushBatchToTop(list, batchStart, i)) {
1349 //If All the non-updating layers with in this batch
1350 //does not have intersection with the updating layers
1351 //above in z-order, then we can safely move the batch to
1352 //higher z-order. Increment fbZ as it is moving up.
1353 if( firstZReverseIndex < 0) {
1354 firstZReverseIndex = i;
1355 }
1356 batchCount++;
1357 batchEnd = i;
1358 fbZ += updatingLayersAbove;
1359 i++;
1360 updatingLayersAbove = 0;
1361 continue;
1362 } else {
1363 //both failed.start the loop again from here.
1364 if(firstZReverseIndex >= 0) {
1365 i = firstZReverseIndex;
1366 }
1367 break;
1368 }
1369 }
1370 }
1371 }
1372 if(batchCount > maxBatchCount) {
1373 maxBatchCount = batchCount;
1374 maxBatchStart = batchStart;
1375 maxBatchEnd = batchEnd;
1376 fbZOrder = fbZ;
1377 }
1378 }
1379 return fbZOrder;
1380}
1381
1382bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1383 hwc_display_contents_1_t* list) {
1384 /* Idea is to keep as many non-updating(cached) layers in FB and
1385 * send rest of them through MDP. This is done in 2 steps.
1386 * 1. Find the maximum contiguous batch of non-updating layers.
1387 * 2. See if we can improve this batch size for caching by adding
1388 * opaque layers around the batch, if they don't have
1389 * any overlapping with the updating layers in between.
1390 * NEVER mark an updating layer for caching.
1391 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001392
1393 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001394 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001395 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301396 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001397
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001398 /* Nothing is cached. No batching needed */
1399 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001400 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001401 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001402
1403 /* No MDP comp layers, try to use other comp modes */
1404 if(mCurrentFrame.mdpCount == 0) {
1405 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001406 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001407
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301408 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001409
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301410 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001411 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001412 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001413 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301414 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001415 if(!mCurrentFrame.drop[i]){
1416 //If an unsupported layer is being attempted to
1417 //be pulled out we should fail
1418 if(not isSupportedForMDPComp(ctx, layer)) {
1419 return false;
1420 }
1421 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001422 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001423 }
1424 }
1425
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301426 // update the frame data
1427 mCurrentFrame.fbZ = fbZ;
1428 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001429 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001430 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001431
1432 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301433 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001434
1435 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001436}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001437
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001438void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001439 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001440 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001441 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001442
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001443 for(int i = 0; i < numAppLayers; i++) {
1444 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001445 if(!mCurrentFrame.drop[i])
1446 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001447 mCurrentFrame.isFBComposed[i] = true;
1448 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001449 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001450 }
1451 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001452
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001453 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001454 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1455 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001456
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001457 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1458 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1459 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001460}
1461
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001462void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1463 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001464 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1465 for(int index = 0;index < nYuvCount; index++){
1466 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1467 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1468
1469 if(!isYUVDoable(ctx, layer)) {
1470 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1471 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1472 mCurrentFrame.fbCount++;
1473 }
1474 } else {
1475 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001476 private_handle_t *hnd = (private_handle_t *)layer->handle;
1477 if(!secureOnly || isSecureBuffer(hnd)) {
1478 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1479 mCurrentFrame.fbCount--;
1480 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001481 }
1482 }
1483 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001484
1485 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001486 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1487 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001488 mCurrentFrame.fbCount);
1489}
1490
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001491hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1492 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001493 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001494
1495 /* Update only the region of FB needed for composition */
1496 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1497 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1498 hwc_layer_1_t* layer = &list->hwLayers[i];
1499 hwc_rect_t dst = layer->displayFrame;
1500 fbRect = getUnion(fbRect, dst);
1501 }
1502 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001503 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001504 return fbRect;
1505}
1506
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001507bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1508 hwc_display_contents_1_t* list) {
1509
1510 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001511 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001512 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1513 return false;
1514 }
1515
1516 //Limitations checks
1517 if(!hwLimitationsCheck(ctx, list)) {
1518 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1519 return false;
1520 }
1521
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001522 //Configure framebuffer first if applicable
1523 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001524 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001525 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1526 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001527 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1528 __FUNCTION__);
1529 return false;
1530 }
1531 }
1532
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001533 mCurrentFrame.map();
1534
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001535 if(!allocLayerPipes(ctx, list)) {
1536 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001537 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001538 }
1539
1540 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001541 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001542 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001543 int mdpIndex = mCurrentFrame.layerToMDP[index];
1544 hwc_layer_1_t* layer = &list->hwLayers[index];
1545
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301546 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1547 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1548 mdpNextZOrder++;
1549 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001550 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1551 cur_pipe->zOrder = mdpNextZOrder++;
1552
radhakrishnac9a67412013-09-25 17:40:42 +05301553 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301554 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301555 if(configure4k2kYuv(ctx, layer,
1556 mCurrentFrame.mdpToLayer[mdpIndex])
1557 != 0 ){
1558 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1559 for layer %d",__FUNCTION__, index);
1560 return false;
1561 }
1562 else{
1563 mdpNextZOrder++;
1564 }
1565 continue;
1566 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001567 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1568 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301569 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001570 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001571 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001572 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001573 }
1574
Saurabh Shaha36be922013-12-16 18:18:39 -08001575 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1576 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1577 ,__FUNCTION__, mDpy);
1578 return false;
1579 }
1580
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001581 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001582 return true;
1583}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001584
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001585bool MDPComp::resourceCheck(hwc_context_t* ctx,
1586 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001587 const bool fbUsed = mCurrentFrame.fbCount;
1588 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1589 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1590 return false;
1591 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001592 // Init rotCount to number of rotate sessions used by other displays
1593 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1594 // Count the number of rotator sessions required for current display
1595 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1596 if(!mCurrentFrame.isFBComposed[index]) {
1597 hwc_layer_1_t* layer = &list->hwLayers[index];
1598 private_handle_t *hnd = (private_handle_t *)layer->handle;
1599 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1600 rotCount++;
1601 }
1602 }
1603 }
1604 // if number of layers to rotate exceeds max rotator sessions, bail out.
1605 if(rotCount > RotMgr::MAX_ROT_SESS) {
1606 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1607 __FUNCTION__, mDpy);
1608 return false;
1609 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001610 return true;
1611}
1612
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301613bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1614 hwc_display_contents_1_t* list) {
1615
1616 //A-family hw limitation:
1617 //If a layer need alpha scaling, MDP can not support.
1618 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1619 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1620 if(!mCurrentFrame.isFBComposed[i] &&
1621 isAlphaScaled( &list->hwLayers[i])) {
1622 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1623 return false;
1624 }
1625 }
1626 }
1627
1628 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1629 //If multiple layers requires downscaling and also they are overlapping
1630 //fall back to GPU since MDSS can not handle it.
1631 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1632 qdutils::MDPVersion::getInstance().is8x26()) {
1633 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1634 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1635 if(!mCurrentFrame.isFBComposed[i] &&
1636 isDownscaleRequired(botLayer)) {
1637 //if layer-i is marked for MDP and needs downscaling
1638 //check if any MDP layer on top of i & overlaps with layer-i
1639 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1640 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1641 if(!mCurrentFrame.isFBComposed[j] &&
1642 isDownscaleRequired(topLayer)) {
1643 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1644 topLayer->displayFrame);
1645 if(isValidRect(r))
1646 return false;
1647 }
1648 }
1649 }
1650 }
1651 }
1652 return true;
1653}
1654
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001655int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001656 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001657 char property[PROPERTY_VALUE_MAX];
1658
Raj Kamal4393eaa2014-06-06 13:45:20 +05301659 if(!ctx || !list) {
1660 ALOGE("%s: Invalid context or list",__FUNCTION__);
1661 mCachedFrame.reset();
1662 return -1;
1663 }
1664
1665 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1666
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001667 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1668 int currentFlags = atoi(property);
1669 if(currentFlags != sSimulationFlags) {
1670 sSimulationFlags = currentFlags;
1671 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1672 sSimulationFlags, sSimulationFlags);
1673 }
1674 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001675 // reset PTOR
1676 if(!mDpy)
1677 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001678
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301679 //Do not cache the information for next draw cycle.
1680 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1681 ALOGI("%s: Unsupported layer count for mdp composition",
1682 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001683 mCachedFrame.reset();
1684 return -1;
1685 }
1686
Saurabh Shahb39f8152013-08-22 10:21:44 -07001687 //reset old data
1688 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001689 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1690 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301691
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001692 // Detect the start of animation and fall back to GPU only once to cache
1693 // all the layers in FB and display FB content untill animation completes.
1694 if(ctx->listStats[mDpy].isDisplayAnimating) {
1695 mCurrentFrame.needsRedraw = false;
1696 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1697 mCurrentFrame.needsRedraw = true;
1698 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1699 }
1700 setMDPCompLayerFlags(ctx, list);
1701 mCachedFrame.updateCounts(mCurrentFrame);
1702 ret = -1;
1703 return ret;
1704 } else {
1705 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1706 }
1707
Saurabh Shahb39f8152013-08-22 10:21:44 -07001708 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001709 if(isFrameDoable(ctx)) {
1710 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001711
Raj Kamal4393eaa2014-06-06 13:45:20 +05301712 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1713 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001714 setMDPCompLayerFlags(ctx, list);
1715 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001716 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001717 reset(ctx);
1718 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1719 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001720 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001721 }
1722 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001723 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1724 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001725 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001726 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001727
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001728 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001729 ALOGD("GEOMETRY change: %d",
1730 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001731 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001732 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001733 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001734 }
1735
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001736 mCachedFrame.cacheAll(list);
1737 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001738 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001739}
1740
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001741bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301742
1743 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301744 int mdpIndex = mCurrentFrame.layerToMDP[index];
1745 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1746 info.pipeInfo = new MdpYUVPipeInfo;
1747 info.rot = NULL;
1748 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301749
1750 pipe_info.lIndex = ovutils::OV_INVALID;
1751 pipe_info.rIndex = ovutils::OV_INVALID;
1752
Saurabh Shahc62f3982014-03-05 14:28:26 -08001753 Overlay::PipeSpecs pipeSpecs;
1754 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1755 pipeSpecs.needsScaling = true;
1756 pipeSpecs.dpy = mDpy;
1757 pipeSpecs.fb = false;
1758
1759 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301760 if(pipe_info.lIndex == ovutils::OV_INVALID){
1761 bRet = false;
1762 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1763 __FUNCTION__);
1764 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001765 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301766 if(pipe_info.rIndex == ovutils::OV_INVALID){
1767 bRet = false;
1768 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1769 __FUNCTION__);
1770 }
1771 return bRet;
1772}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001773
1774int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1775 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001776 if (ctx->mPtorInfo.isActive()) {
1777 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001778 if (fd < 0) {
1779 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001780 }
1781 }
1782 return fd;
1783}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001784//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001785
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001786void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301787 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001788 //If 4k2k Yuv layer split is possible, and if
1789 //fbz is above 4k2k layer, increment fb zorder by 1
1790 //as we split 4k2k layer and increment zorder for right half
1791 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001792 if(!ctx)
1793 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001794 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301795 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1796 index++) {
1797 if(!mCurrentFrame.isFBComposed[index]) {
1798 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1799 mdpNextZOrder++;
1800 }
1801 mdpNextZOrder++;
1802 hwc_layer_1_t* layer = &list->hwLayers[index];
1803 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301804 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301805 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1806 mCurrentFrame.fbZ += 1;
1807 mdpNextZOrder++;
1808 //As we split 4kx2k yuv layer and program to 2 VG pipes
1809 //(if available) increase mdpcount by 1.
1810 mCurrentFrame.mdpCount++;
1811 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001812 }
1813 }
1814 }
radhakrishnac9a67412013-09-25 17:40:42 +05301815}
1816
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001817/*
1818 * Configures pipe(s) for MDP composition
1819 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001820int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001821 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001822 MdpPipeInfoNonSplit& mdp_info =
1823 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001824 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1825 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1826 eIsFg isFg = IS_FG_OFF;
1827 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001828
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001829 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1830 __FUNCTION__, layer, zOrder, dest);
1831
Saurabh Shah88e4d272013-09-03 13:31:29 -07001832 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001833 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001834}
1835
Saurabh Shah88e4d272013-09-03 13:31:29 -07001836bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001837 hwc_display_contents_1_t* list) {
1838 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001839
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001840 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001841
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001842 hwc_layer_1_t* layer = &list->hwLayers[index];
1843 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301844 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001845 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301846 continue;
1847 }
1848 }
1849
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001850 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001851 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001852 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001853 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001854 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001855
Saurabh Shahc62f3982014-03-05 14:28:26 -08001856 Overlay::PipeSpecs pipeSpecs;
1857 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1858 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1859 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1860 (qdutils::MDPVersion::getInstance().is8x26() and
1861 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1862 pipeSpecs.dpy = mDpy;
1863 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001864 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001865
Saurabh Shahc62f3982014-03-05 14:28:26 -08001866 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1867
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001868 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001869 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001870 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001871 }
1872 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001873 return true;
1874}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001875
radhakrishnac9a67412013-09-25 17:40:42 +05301876int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1877 PipeLayerPair& PipeLayerPair) {
1878 MdpYUVPipeInfo& mdp_info =
1879 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1880 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1881 eIsFg isFg = IS_FG_OFF;
1882 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1883 eDest lDest = mdp_info.lIndex;
1884 eDest rDest = mdp_info.rIndex;
1885
1886 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1887 lDest, rDest, &PipeLayerPair.rot);
1888}
1889
Saurabh Shah88e4d272013-09-03 13:31:29 -07001890bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001891
Raj Kamal4393eaa2014-06-06 13:45:20 +05301892 if(!isEnabled() or !mModeOn) {
1893 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301894 return true;
1895 }
1896
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001897 // Set the Handle timeout to true for MDP or MIXED composition.
1898 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1899 sHandleTimeout = true;
1900 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001901
1902 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001903 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001904
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001905 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1906 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001907 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001908 if(mCurrentFrame.isFBComposed[i]) continue;
1909
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001910 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001911 private_handle_t *hnd = (private_handle_t *)layer->handle;
1912 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001913 if (!(layer->flags & HWC_COLOR_FILL)) {
1914 ALOGE("%s handle null", __FUNCTION__);
1915 return false;
1916 }
1917 // No PLAY for Color layer
1918 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1919 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001920 }
1921
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001922 int mdpIndex = mCurrentFrame.layerToMDP[i];
1923
Raj Kamal389d6e32014-08-04 14:43:24 +05301924 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05301925 {
1926 MdpYUVPipeInfo& pipe_info =
1927 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1928 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1929 ovutils::eDest indexL = pipe_info.lIndex;
1930 ovutils::eDest indexR = pipe_info.rIndex;
1931 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301932 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301933 if(rot) {
1934 rot->queueBuffer(fd, offset);
1935 fd = rot->getDstMemId();
1936 offset = rot->getDstOffset();
1937 }
1938 if(indexL != ovutils::OV_INVALID) {
1939 ovutils::eDest destL = (ovutils::eDest)indexL;
1940 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1941 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1942 if (!ov.queueBuffer(fd, offset, destL)) {
1943 ALOGE("%s: queueBuffer failed for display:%d",
1944 __FUNCTION__, mDpy);
1945 return false;
1946 }
1947 }
1948
1949 if(indexR != ovutils::OV_INVALID) {
1950 ovutils::eDest destR = (ovutils::eDest)indexR;
1951 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1952 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1953 if (!ov.queueBuffer(fd, offset, destR)) {
1954 ALOGE("%s: queueBuffer failed for display:%d",
1955 __FUNCTION__, mDpy);
1956 return false;
1957 }
1958 }
1959 }
1960 else{
1961 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001962 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301963 ovutils::eDest dest = pipe_info.index;
1964 if(dest == ovutils::OV_INVALID) {
1965 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001966 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301967 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001968
radhakrishnac9a67412013-09-25 17:40:42 +05301969 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1970 continue;
1971 }
1972
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001973 int fd = hnd->fd;
1974 uint32_t offset = (uint32_t)hnd->offset;
1975 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1976 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001977 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001978 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001979 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001980 }
1981
radhakrishnac9a67412013-09-25 17:40:42 +05301982 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1983 using pipe: %d", __FUNCTION__, layer,
1984 hnd, dest );
1985
radhakrishnac9a67412013-09-25 17:40:42 +05301986 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1987 if(rot) {
1988 if(!rot->queueBuffer(fd, offset))
1989 return false;
1990 fd = rot->getDstMemId();
1991 offset = rot->getDstOffset();
1992 }
1993
1994 if (!ov.queueBuffer(fd, offset, dest)) {
1995 ALOGE("%s: queueBuffer failed for display:%d ",
1996 __FUNCTION__, mDpy);
1997 return false;
1998 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001999 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002000
2001 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002002 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002003 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002004}
2005
Saurabh Shah88e4d272013-09-03 13:31:29 -07002006//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002007
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002008void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302009 hwc_display_contents_1_t* list){
2010 //if 4kx2k yuv layer is totally present in either in left half
2011 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302012 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302013 if(mCurrentFrame.fbZ >= 0) {
2014 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2015 index++) {
2016 if(!mCurrentFrame.isFBComposed[index]) {
2017 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2018 mdpNextZOrder++;
2019 }
2020 mdpNextZOrder++;
2021 hwc_layer_1_t* layer = &list->hwLayers[index];
2022 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302023 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302024 hwc_rect_t dst = layer->displayFrame;
2025 if((dst.left > lSplit) || (dst.right < lSplit)) {
2026 mCurrentFrame.mdpCount += 1;
2027 }
2028 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2029 mCurrentFrame.fbZ += 1;
2030 mdpNextZOrder++;
2031 }
2032 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002033 }
radhakrishnac9a67412013-09-25 17:40:42 +05302034 }
2035}
2036
Saurabh Shah88e4d272013-09-03 13:31:29 -07002037bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002038 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002039
Saurabh Shahc62f3982014-03-05 14:28:26 -08002040 const int lSplit = getLeftSplit(ctx, mDpy);
2041 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002042 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002043 pipe_info.lIndex = ovutils::OV_INVALID;
2044 pipe_info.rIndex = ovutils::OV_INVALID;
2045
Saurabh Shahc62f3982014-03-05 14:28:26 -08002046 Overlay::PipeSpecs pipeSpecs;
2047 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2048 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2049 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2050 pipeSpecs.dpy = mDpy;
2051 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2052 pipeSpecs.fb = false;
2053
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002054 // Acquire pipe only for the updating half
2055 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2056 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2057
2058 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002059 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002060 if(pipe_info.lIndex == ovutils::OV_INVALID)
2061 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002062 }
2063
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002064 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002065 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2066 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002067 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002068 return false;
2069 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002070
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002071 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002072}
2073
Saurabh Shah88e4d272013-09-03 13:31:29 -07002074bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002075 hwc_display_contents_1_t* list) {
2076 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002077
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002078 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002079
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002080 hwc_layer_1_t* layer = &list->hwLayers[index];
2081 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302082 hwc_rect_t dst = layer->displayFrame;
2083 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302084 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302085 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002086 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302087 continue;
2088 }
2089 }
2090 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002091 int mdpIndex = mCurrentFrame.layerToMDP[index];
2092 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002093 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002094 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002095 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002096
Saurabh Shahc62f3982014-03-05 14:28:26 -08002097 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2098 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2099 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002100 return false;
2101 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002102 }
2103 return true;
2104}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002105
radhakrishnac9a67412013-09-25 17:40:42 +05302106int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2107 PipeLayerPair& PipeLayerPair) {
2108 const int lSplit = getLeftSplit(ctx, mDpy);
2109 hwc_rect_t dst = layer->displayFrame;
2110 if((dst.left > lSplit)||(dst.right < lSplit)){
2111 MdpYUVPipeInfo& mdp_info =
2112 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2113 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2114 eIsFg isFg = IS_FG_OFF;
2115 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2116 eDest lDest = mdp_info.lIndex;
2117 eDest rDest = mdp_info.rIndex;
2118
2119 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2120 lDest, rDest, &PipeLayerPair.rot);
2121 }
2122 else{
2123 return configure(ctx, layer, PipeLayerPair);
2124 }
2125}
2126
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002127/*
2128 * Configures pipe(s) for MDP composition
2129 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002130int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002131 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002132 MdpPipeInfoSplit& mdp_info =
2133 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002134 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2135 eIsFg isFg = IS_FG_OFF;
2136 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2137 eDest lDest = mdp_info.lIndex;
2138 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002139
2140 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2141 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2142
Saurabh Shah88e4d272013-09-03 13:31:29 -07002143 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002144 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002145}
2146
Saurabh Shah88e4d272013-09-03 13:31:29 -07002147bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002148
Raj Kamal4393eaa2014-06-06 13:45:20 +05302149 if(!isEnabled() or !mModeOn) {
2150 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302151 return true;
2152 }
2153
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002154 // Set the Handle timeout to true for MDP or MIXED composition.
2155 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2156 sHandleTimeout = true;
2157 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002158
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002159 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002160 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002161
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002162 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2163 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002164 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002165 if(mCurrentFrame.isFBComposed[i]) continue;
2166
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002167 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002168 private_handle_t *hnd = (private_handle_t *)layer->handle;
2169 if(!hnd) {
2170 ALOGE("%s handle null", __FUNCTION__);
2171 return false;
2172 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002173
2174 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2175 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002176 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002177
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002178 int mdpIndex = mCurrentFrame.layerToMDP[i];
2179
Raj Kamal389d6e32014-08-04 14:43:24 +05302180 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302181 {
2182 MdpYUVPipeInfo& pipe_info =
2183 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2184 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2185 ovutils::eDest indexL = pipe_info.lIndex;
2186 ovutils::eDest indexR = pipe_info.rIndex;
2187 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302188 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302189 if(rot) {
2190 rot->queueBuffer(fd, offset);
2191 fd = rot->getDstMemId();
2192 offset = rot->getDstOffset();
2193 }
2194 if(indexL != ovutils::OV_INVALID) {
2195 ovutils::eDest destL = (ovutils::eDest)indexL;
2196 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2197 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2198 if (!ov.queueBuffer(fd, offset, destL)) {
2199 ALOGE("%s: queueBuffer failed for display:%d",
2200 __FUNCTION__, mDpy);
2201 return false;
2202 }
2203 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002204
radhakrishnac9a67412013-09-25 17:40:42 +05302205 if(indexR != ovutils::OV_INVALID) {
2206 ovutils::eDest destR = (ovutils::eDest)indexR;
2207 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2208 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2209 if (!ov.queueBuffer(fd, offset, destR)) {
2210 ALOGE("%s: queueBuffer failed for display:%d",
2211 __FUNCTION__, mDpy);
2212 return false;
2213 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002214 }
2215 }
radhakrishnac9a67412013-09-25 17:40:42 +05302216 else{
2217 MdpPipeInfoSplit& pipe_info =
2218 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2219 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002220
radhakrishnac9a67412013-09-25 17:40:42 +05302221 ovutils::eDest indexL = pipe_info.lIndex;
2222 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002223
radhakrishnac9a67412013-09-25 17:40:42 +05302224 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002225 uint32_t offset = (uint32_t)hnd->offset;
2226 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2227 if (!mDpy && (index != -1)) {
2228 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2229 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002230 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002231 }
radhakrishnac9a67412013-09-25 17:40:42 +05302232
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002233 if(ctx->mAD->draw(ctx, fd, offset)) {
2234 fd = ctx->mAD->getDstFd();
2235 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002236 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002237
radhakrishnac9a67412013-09-25 17:40:42 +05302238 if(rot) {
2239 rot->queueBuffer(fd, offset);
2240 fd = rot->getDstMemId();
2241 offset = rot->getDstOffset();
2242 }
2243
2244 //************* play left mixer **********
2245 if(indexL != ovutils::OV_INVALID) {
2246 ovutils::eDest destL = (ovutils::eDest)indexL;
2247 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2248 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2249 if (!ov.queueBuffer(fd, offset, destL)) {
2250 ALOGE("%s: queueBuffer failed for left mixer",
2251 __FUNCTION__);
2252 return false;
2253 }
2254 }
2255
2256 //************* play right mixer **********
2257 if(indexR != ovutils::OV_INVALID) {
2258 ovutils::eDest destR = (ovutils::eDest)indexR;
2259 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2260 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2261 if (!ov.queueBuffer(fd, offset, destR)) {
2262 ALOGE("%s: queueBuffer failed for right mixer",
2263 __FUNCTION__);
2264 return false;
2265 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002266 }
2267 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002268
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002269 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2270 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002271
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002272 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002273}
Saurabh Shahab47c692014-02-12 18:45:57 -08002274
2275//================MDPCompSrcSplit==============================================
2276bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002277 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002278 private_handle_t *hnd = (private_handle_t *)layer->handle;
2279 hwc_rect_t dst = layer->displayFrame;
2280 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2281 pipe_info.lIndex = ovutils::OV_INVALID;
2282 pipe_info.rIndex = ovutils::OV_INVALID;
2283
2284 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2285 //should have a higher priority than the right one. Pipe priorities are
2286 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002287
Saurabh Shahc62f3982014-03-05 14:28:26 -08002288 Overlay::PipeSpecs pipeSpecs;
2289 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2290 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2291 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2292 pipeSpecs.dpy = mDpy;
2293 pipeSpecs.fb = false;
2294
Saurabh Shahab47c692014-02-12 18:45:57 -08002295 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002296 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002297 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002298 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002299 }
2300
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002301 /* Use 2 pipes IF
2302 a) Layer's crop width is > 2048 or
2303 b) Layer's dest width > 2048 or
2304 c) On primary, driver has indicated with caps to split always. This is
2305 based on an empirically derived value of panel height. Applied only
2306 if the layer's width is > mixer's width
2307 */
2308
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302309 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002310 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302311 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002312 int lSplit = getLeftSplit(ctx, mDpy);
2313 int dstWidth = dst.right - dst.left;
2314 int cropWidth = crop.right - crop.left;
2315
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002316 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2317 //pipe line length, we are still using 2 pipes. This is fine just because
2318 //this is source split where destination doesn't matter. Evaluate later to
2319 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302320 if(dstWidth > mdpHw.getMaxMixerWidth() or
2321 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002322 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002323 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002324 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002325 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002326 }
2327
2328 // Return values
2329 // 1 Left pipe is higher priority, do nothing.
2330 // 0 Pipes of same priority.
2331 //-1 Right pipe is of higher priority, needs swap.
2332 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2333 pipe_info.rIndex) == -1) {
2334 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002335 }
2336 }
2337
2338 return true;
2339}
2340
Saurabh Shahab47c692014-02-12 18:45:57 -08002341int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2342 PipeLayerPair& PipeLayerPair) {
2343 private_handle_t *hnd = (private_handle_t *)layer->handle;
2344 if(!hnd) {
2345 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2346 return -1;
2347 }
2348 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2349 MdpPipeInfoSplit& mdp_info =
2350 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2351 Rotator **rot = &PipeLayerPair.rot;
2352 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2353 eIsFg isFg = IS_FG_OFF;
2354 eDest lDest = mdp_info.lIndex;
2355 eDest rDest = mdp_info.rIndex;
2356 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2357 hwc_rect_t dst = layer->displayFrame;
2358 int transform = layer->transform;
2359 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002360 int rotFlags = ROT_FLAGS_NONE;
2361 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2362 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2363
2364 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2365 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2366
2367 // Handle R/B swap
2368 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2369 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2370 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2371 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2372 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2373 }
2374
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002375 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002376 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002377 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002378
2379 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2380 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002381 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002382 }
2383
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002384 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002385 (*rot) = ctx->mRotMgr->getNext();
2386 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002387 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002388 //If the video is using a single pipe, enable BWC
2389 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002390 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002391 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002392 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002393 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002394 ALOGE("%s: configRotator failed!", __FUNCTION__);
2395 return -1;
2396 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002397 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002398 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002399 }
2400
2401 //If 2 pipes being used, divide layer into half, crop and dst
2402 hwc_rect_t cropL = crop;
2403 hwc_rect_t cropR = crop;
2404 hwc_rect_t dstL = dst;
2405 hwc_rect_t dstR = dst;
2406 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2407 cropL.right = (crop.right + crop.left) / 2;
2408 cropR.left = cropL.right;
2409 sanitizeSourceCrop(cropL, cropR, hnd);
2410
2411 //Swap crops on H flip since 2 pipes are being used
2412 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2413 hwc_rect_t tmp = cropL;
2414 cropL = cropR;
2415 cropR = tmp;
2416 }
2417
2418 dstL.right = (dst.right + dst.left) / 2;
2419 dstR.left = dstL.right;
2420 }
2421
2422 //For the mdp, since either we are pre-rotating or MDP does flips
2423 orient = OVERLAY_TRANSFORM_0;
2424 transform = 0;
2425
2426 //configure left pipe
2427 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002428 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002429 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2430 (ovutils::eBlending) getBlending(layer->blending));
2431
2432 if(configMdp(ctx->mOverlay, pargL, orient,
2433 cropL, dstL, metadata, lDest) < 0) {
2434 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2435 return -1;
2436 }
2437 }
2438
2439 //configure right pipe
2440 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002441 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002442 static_cast<eRotFlags>(rotFlags),
2443 layer->planeAlpha,
2444 (ovutils::eBlending) getBlending(layer->blending));
2445 if(configMdp(ctx->mOverlay, pargR, orient,
2446 cropR, dstR, metadata, rDest) < 0) {
2447 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2448 return -1;
2449 }
2450 }
2451
2452 return 0;
2453}
2454
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002455}; //namespace
2456