blob: 0a38b1068a335a39073a0ae8e23ecabe116082aa [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
radhakrishnac9a67412013-09-25 17:40:42 +053048bool MDPComp::sEnable4k2kYUVSplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800130 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
131 if(atoi(property) != 0)
132 sDebugLogs = true;
133 }
134
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700136 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
137 int val = atoi(property);
138 if(val >= 0)
139 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800140 }
141
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400142 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
143 // Idle invalidation is not necessary on command mode panels
144 long idle_timeout = DEFAULT_IDLE_TIME;
145 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
146 if(atoi(property) != 0)
147 idle_timeout = atoi(property);
148 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800149
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400150 //create Idle Invalidator only when not disabled through property
151 if(idle_timeout != -1)
152 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800153
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400154 if(idleInvalidator == NULL) {
155 ALOGE("%s: failed to instantiate idleInvalidator object",
156 __FUNCTION__);
157 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530158 idleInvalidator->init(timeout_handler, ctx,
159 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800161 }
radhakrishnac9a67412013-09-25 17:40:42 +0530162
Saurabh Shah7c727642014-06-02 15:47:14 -0700163 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
164 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
165 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
166 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
radhakrishnac9a67412013-09-25 17:40:42 +0530167 sEnable4k2kYUVSplit = true;
168 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700169
170 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
171 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
172 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
173 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
174 HWC_DISPLAY_PRIMARY);
175 }
176
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700177 return true;
178}
179
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800180void MDPComp::reset(hwc_context_t *ctx) {
181 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700182 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800183 ctx->mOverlay->clear(mDpy);
184 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700185}
186
Raj Kamal4393eaa2014-06-06 13:45:20 +0530187void MDPComp::reset() {
188 sHandleTimeout = false;
189 mModeOn = false;
190}
191
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700192void MDPComp::timeout_handler(void *udata) {
193 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
194
195 if(!ctx) {
196 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
197 return;
198 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800199 Locker::Autolock _l(ctx->mDrawLock);
200 // Handle timeout event only if the previous composition is MDP or MIXED.
201 if(!sHandleTimeout) {
202 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
203 return;
204 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700205 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700206 ALOGE("%s: HWC proc not registered", __FUNCTION__);
207 return;
208 }
209 sIdleFallBack = true;
210 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700211 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212}
213
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 hwc_display_contents_1_t* list) {
216 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800217
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800218 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800219 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220 if(!mCurrentFrame.isFBComposed[index]) {
221 layerProp[index].mFlags |= HWC_MDPCOMP;
222 layer->compositionType = HWC_OVERLAY;
223 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800224 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700225 /* Drop the layer when its already present in FB OR when it lies
226 * outside frame's ROI */
227 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800228 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700229 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800230 }
231 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500233
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800234void MDPComp::setRedraw(hwc_context_t *ctx,
235 hwc_display_contents_1_t* list) {
236 mCurrentFrame.needsRedraw = false;
237 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
238 (list->flags & HWC_GEOMETRY_CHANGED) ||
239 isSkipPresent(ctx, mDpy)) {
240 mCurrentFrame.needsRedraw = true;
241 }
242}
243
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800244MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700245 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800247
Saurabh Shahaa236822013-04-24 18:07:26 -0700248void MDPComp::FrameInfo::reset(const int& numLayers) {
249 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800250 if(mdpToLayer[i].pipeInfo) {
251 delete mdpToLayer[i].pipeInfo;
252 mdpToLayer[i].pipeInfo = NULL;
253 //We dont own the rotator
254 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800255 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800256 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
258 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
259 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700260 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261
Saurabh Shahaa236822013-04-24 18:07:26 -0700262 layerCount = numLayers;
263 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700265 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800266 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800267}
268
Saurabh Shahaa236822013-04-24 18:07:26 -0700269void MDPComp::FrameInfo::map() {
270 // populate layer and MDP maps
271 int mdpIdx = 0;
272 for(int idx = 0; idx < layerCount; idx++) {
273 if(!isFBComposed[idx]) {
274 mdpToLayer[mdpIdx].listIndex = idx;
275 layerToMDP[idx] = mdpIdx++;
276 }
277 }
278}
279
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800280MDPComp::LayerCache::LayerCache() {
281 reset();
282}
283
284void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700285 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530286 memset(&isFBComposed, true, sizeof(isFBComposed));
287 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800288 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289}
290
291void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530292 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700293 for(int i = 0; i < numAppLayers; i++) {
294 hnd[i] = list->hwLayers[i].handle;
295 }
296}
297
298void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700299 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530300 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
301 memcpy(&drop, &curFrame.drop, sizeof(drop));
302}
303
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800304bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
305 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530306 if(layerCount != curFrame.layerCount)
307 return false;
308 for(int i = 0; i < curFrame.layerCount; i++) {
309 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
310 (curFrame.drop[i] != drop[i])) {
311 return false;
312 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800313 if(curFrame.isFBComposed[i] &&
314 (hnd[i] != list->hwLayers[i].handle)){
315 return false;
316 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530317 }
318 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800319}
320
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700321bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
322 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800323 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700324 (not isValidDimension(ctx,layer))
325 //More conditions here, SKIP, sRGB+Blend etc
326 ) {
327 return false;
328 }
329 return true;
330}
331
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530332bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800333 private_handle_t *hnd = (private_handle_t *)layer->handle;
334
335 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700336 if (layer->flags & HWC_COLOR_FILL) {
337 // Color layer
338 return true;
339 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800340 ALOGE("%s: layer handle is NULL", __FUNCTION__);
341 return false;
342 }
343
Naseer Ahmede850a802013-09-06 13:12:52 -0400344 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400345 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400346 return false;
347
Saurabh Shah62e1d732013-09-17 10:44:05 -0700348 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700350 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700351 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
352 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700353 int dst_w = dst.right - dst.left;
354 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800355 float w_scale = ((float)crop_w / (float)dst_w);
356 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700357
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800358 /* Workaround for MDP HW limitation in DSI command mode panels where
359 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
360 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530361 * There also is a HW limilation in MDP, minimum block size is 2x2
362 * Fallback to GPU if height is less than 2.
363 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800364 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800365 return false;
366
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800367 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700368 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700369 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800370 const float w_dscale = w_scale;
371 const float h_dscale = h_scale;
372
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800373 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700374
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800375 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700376 /* On targets that doesnt support Decimation (eg.,8x26)
377 * maximum downscale support is overlay pipe downscale.
378 */
379 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
380 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800381 return false;
382 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700383 // Decimation on macrotile format layers is not supported.
384 if(isTileRendered(hnd)) {
385 /* MDP can read maximum MAX_DISPLAY_DIM width.
386 * Bail out if
387 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
388 * 2. exceeds maximum downscale limit
389 */
390 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
391 w_dscale > maxMDPDownscale ||
392 h_dscale > maxMDPDownscale) {
393 return false;
394 }
395 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800396 return false;
397 }
398 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700399 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700400 return false;
401 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700402 }
403
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800404 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
405 const uint32_t upscale =
406 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
407 const float w_uscale = 1.0f / w_scale;
408 const float h_uscale = 1.0f / h_scale;
409
410 if(w_uscale > upscale || h_uscale > upscale)
411 return false;
412 }
413
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800414 return true;
415}
416
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800417bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800419
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800420 if(!isEnabled()) {
421 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700422 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530423 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530424 qdutils::MDPVersion::getInstance().is8x16() ||
425 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800426 ctx->mVideoTransFlag &&
427 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700428 //1 Padding round to shift pipes across mixers
429 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
430 __FUNCTION__);
431 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800432 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800433 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800434 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530437 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
438 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700439 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700440 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700441 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800442}
443
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800444void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
445 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
446 fbRect = getIntersection(fbRect, roi);
447}
448
449/* 1) Identify layers that are not visible or lying outside the updating ROI and
450 * drop them from composition.
451 * 2) If we have a scaling layer which needs cropping against generated
452 * ROI, reset ROI to full resolution. */
453bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
454 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700455 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800456 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800457
458 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800459 if(!isValidRect(visibleRect)) {
460 mCurrentFrame.drop[i] = true;
461 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800462 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800463 }
464
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700466 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800467 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 if(!isValidRect(res)) {
470 mCurrentFrame.drop[i] = true;
471 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800472 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700473 /* Reset frame ROI when any layer which needs scaling also needs ROI
474 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800475 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800476 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700477 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
478 mCurrentFrame.dropCount = 0;
479 return false;
480 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800481
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800482 /* deduct any opaque region from visibleRect */
483 if (layer->blending == HWC_BLENDING_NONE)
484 visibleRect = deductRect(visibleRect, res);
485 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700486 }
487 return true;
488}
489
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800490/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
491 * are updating. If DirtyRegion is applicable, calculate it by accounting all
492 * the changing layer's dirtyRegion. */
493void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
494 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700495 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700497 return;
498
499 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800500 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
501 (int)ctx->dpyAttr[mDpy].yres};
502
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700503 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800504 hwc_layer_1_t* layer = &list->hwLayers[index];
505 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800506 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700507 hwc_rect_t dst = layer->displayFrame;
508 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800510#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800511 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700512 {
513 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
514 int x_off = dst.left - src.left;
515 int y_off = dst.top - src.top;
516 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
517 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800518#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800520 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700521 }
522 }
523
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800524 /* No layer is updating. Still SF wants a refresh.*/
525 if(!isValidRect(roi))
526 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800527
528 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800529 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800530
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800531 ctx->listStats[mDpy].lRoi = roi;
532 if(!validateAndApplyROI(ctx, list))
533 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534
535 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800536 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
537 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
538}
539
540void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
541 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
542 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
543
544 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
545 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
546 fbRect = getUnion(l_fbRect, r_fbRect);
547}
548/* 1) Identify layers that are not visible or lying outside BOTH the updating
549 * ROI's and drop them from composition. If a layer is spanning across both
550 * the halves of the screen but needed by only ROI, the non-contributing
551 * half will not be programmed for MDP.
552 * 2) If we have a scaling layer which needs cropping against generated
553 * ROI, reset ROI to full resolution. */
554bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
555 hwc_display_contents_1_t* list) {
556
557 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
558
559 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
560 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
561
562 for(int i = numAppLayers - 1; i >= 0; i--){
563 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
564 {
565 mCurrentFrame.drop[i] = true;
566 mCurrentFrame.dropCount++;
567 continue;
568 }
569
570 const hwc_layer_1_t* layer = &list->hwLayers[i];
571 hwc_rect_t dstRect = layer->displayFrame;
572
573 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
574 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
575 hwc_rect_t res = getUnion(l_res, r_res);
576
577 if(!isValidRect(l_res) && !isValidRect(r_res)) {
578 mCurrentFrame.drop[i] = true;
579 mCurrentFrame.dropCount++;
580 } else {
581 /* Reset frame ROI when any layer which needs scaling also needs ROI
582 * cropping */
583 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
584 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
585 mCurrentFrame.dropCount = 0;
586 return false;
587 }
588
589 if (layer->blending == HWC_BLENDING_NONE) {
590 visibleRectL = deductRect(visibleRectL, l_res);
591 visibleRectR = deductRect(visibleRectR, r_res);
592 }
593 }
594 }
595 return true;
596}
597/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
598 * are updating. If DirtyRegion is applicable, calculate it by accounting all
599 * the changing layer's dirtyRegion. */
600void MDPCompSplit::generateROI(hwc_context_t *ctx,
601 hwc_display_contents_1_t* list) {
602 if(!canPartialUpdate(ctx, list))
603 return;
604
605 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
606 int lSplit = getLeftSplit(ctx, mDpy);
607
608 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
609 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
610
611 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
612 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
613
614 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
615 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
616
617 for(int index = 0; index < numAppLayers; index++ ) {
618 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800619 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800620 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800621 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700622 hwc_rect_t dst = layer->displayFrame;
623 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800624
625#ifdef QCOM_BSP
626 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700627 {
628 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
629 int x_off = dst.left - src.left;
630 int y_off = dst.top - src.top;
631 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
632 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800633#endif
634
635 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
636 if(isValidRect(l_dst))
637 l_roi = getUnion(l_roi, l_dst);
638
639 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
640 if(isValidRect(r_dst))
641 r_roi = getUnion(r_roi, r_dst);
642 }
643 }
644
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700645 /* For panels that cannot accept commands in both the interfaces, we cannot
646 * send two ROI's (for each half). We merge them into single ROI and split
647 * them across lSplit for MDP mixer use. The ROI's will be merged again
648 * finally before udpating the panel in the driver. */
649 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
650 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
651 l_roi = getIntersection(temp_roi, l_frame);
652 r_roi = getIntersection(temp_roi, r_frame);
653 }
654
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800655 /* No layer is updating. Still SF wants a refresh. */
656 if(!isValidRect(l_roi) && !isValidRect(r_roi))
657 return;
658
659 l_roi = getSanitizeROI(l_roi, l_frame);
660 r_roi = getSanitizeROI(r_roi, r_frame);
661
662 ctx->listStats[mDpy].lRoi = l_roi;
663 ctx->listStats[mDpy].rRoi = r_roi;
664
665 if(!validateAndApplyROI(ctx, list))
666 resetROI(ctx, mDpy);
667
668 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
669 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
670 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
671 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
672 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
673 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700674}
675
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800676/* Checks for conditions where all the layers marked for MDP comp cannot be
677 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800678bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800679 hwc_display_contents_1_t* list){
680
Saurabh Shahaa236822013-04-24 18:07:26 -0700681 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800682 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800683
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700684 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700685 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
686 return false;
687 }
688
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800689 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700690 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
691 __FUNCTION__,
692 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800693 return false;
694 }
695
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800696 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
697 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
698 // Disable MDP comp on Secondary when the primary is highres panel and
699 // the secondary is a normal 1080p, because, MDP comp on secondary under
700 // in such usecase, decimation gets used for downscale and there will be
701 // a quality mismatch when there will be a fallback to GPU comp
702 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
703 __FUNCTION__);
704 return false;
705 }
706
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800707 // check for action safe flag and downscale mode which requires scaling.
708 if(ctx->dpyAttr[mDpy].mActionSafePresent
709 || ctx->dpyAttr[mDpy].mDownScaleMode) {
710 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
711 return false;
712 }
713
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800714 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800715 hwc_layer_1_t* layer = &list->hwLayers[i];
716 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800717
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800718 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700719 if(!canUseRotator(ctx, mDpy)) {
720 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
721 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700722 return false;
723 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800724 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530725
726 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
727 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700728 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530729 if(qdutils::MDPVersion::getInstance().is8x26() &&
730 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700731 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530732 (!isYuvBuffer(hnd)))
733 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800734 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700735
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700736 if(ctx->mAD->isDoable()) {
737 return false;
738 }
739
Saurabh Shahaa236822013-04-24 18:07:26 -0700740 //If all above hard conditions are met we can do full or partial MDP comp.
741 bool ret = false;
742 if(fullMDPComp(ctx, list)) {
743 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700744 } else if(fullMDPCompWithPTOR(ctx, list)) {
745 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700746 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700747 ret = true;
748 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530749
Saurabh Shahaa236822013-04-24 18:07:26 -0700750 return ret;
751}
752
753bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700754
755 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
756 return false;
757
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700758 //Will benefit presentation / secondary-only layer.
759 if((mDpy > HWC_DISPLAY_PRIMARY) &&
760 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
761 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
762 return false;
763 }
764
765 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
766 for(int i = 0; i < numAppLayers; i++) {
767 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700768 if(not mCurrentFrame.drop[i] and
769 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700770 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
771 return false;
772 }
773 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800774
Saurabh Shahaa236822013-04-24 18:07:26 -0700775 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700776 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
777 sizeof(mCurrentFrame.isFBComposed));
778 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
779 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700780
radhakrishnac9a67412013-09-25 17:40:42 +0530781 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800782 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530783 }
784
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800785 if(!postHeuristicsHandling(ctx, list)) {
786 ALOGD_IF(isDebug(), "post heuristic handling failed");
787 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700788 return false;
789 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700790 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
791 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700792 return true;
793}
794
Sushil Chauhandefd3522014-05-13 18:17:12 -0700795/* Full MDP Composition with Peripheral Tiny Overlap Removal.
796 * MDP bandwidth limitations can be avoided, if the overlap region
797 * covered by the smallest layer at a higher z-order, gets composed
798 * by Copybit on a render buffer, which can be queued to MDP.
799 */
800bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
801 hwc_display_contents_1_t* list) {
802
803 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
804 const int stagesForMDP = min(sMaxPipesPerMixer,
805 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
806
807 // Hard checks where we cannot use this mode
808 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
809 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
810 return false;
811 }
812
813 // Frame level checks
814 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
815 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
816 isSecurePresent(ctx, mDpy)) {
817 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
818 return false;
819 }
820
821 // Find overlap index
822 int overlapIdx = numAppLayers - 1;
823 uint32_t layerPixelCount, minPixelCount = 0;
824 for (int i = numAppLayers - 1; i >= 0; i--) {
825 hwc_layer_1_t* layer = &list->hwLayers[i];
826 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
827 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
828 if (!minPixelCount || (layerPixelCount < minPixelCount)) {
829 minPixelCount = layerPixelCount;
830 overlapIdx = i;
831 }
832 }
833
834 // No overlap
835 if (!overlapIdx)
836 return false;
837
838 /* We cannot use this composition mode, if:
839 1. A below layer needs scaling.
840 2. Overlap is not peripheral to display.
841 3. Overlap or a below layer has 90 degree transform.
842 4. Intersection of Overlap layer with a below layer is not valid.
843 5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
844 */
845
846 hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
847 if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
848 return false;
849
850 if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
851 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
852 return false;
853
854 for (int i = overlapIdx; i >= 0; i--) {
855 hwc_layer_1_t* layer = &list->hwLayers[i];
856 hwc_rect_t dispFrame = layer->displayFrame;
857
858 if (has90Transform(layer))
859 return false;
860
861 if (i < overlapIdx) {
862 if (needsScaling(layer) ||
863 !isValidRect(getIntersection(dispFrame, overlap)))
864 return false;
865 }
866 }
867
868 mOverlapIndex = overlapIdx;
869 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
870 ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
871 mOverlapIndex = -1;
872 return false;
873 }
874
875 hwc_rect_t sourceCrop[overlapIdx];
876 hwc_rect_t displayFrame[overlapIdx];
877
878 // Remove overlap from crop & displayFrame of below layers
879 for (int i = 0; i < overlapIdx; i++) {
880 hwc_layer_1_t* layer = &list->hwLayers[i];
881 displayFrame[i] = layer->displayFrame;
882 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
883
884 // Update layer attributes
885 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
886 hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
887 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
888 layer->transform);
889
890 layer->sourceCropf.left = (float)srcCrop.left;
891 layer->sourceCropf.top = (float)srcCrop.top;
892 layer->sourceCropf.right = (float)srcCrop.right;
893 layer->sourceCropf.bottom = (float)srcCrop.bottom;
894 }
895
896 mCurrentFrame.mdpCount = numAppLayers;
897 mCurrentFrame.fbCount = 0;
898 mCurrentFrame.fbZ = -1;
899
900 for (int j = 0; j < numAppLayers; j++)
901 mCurrentFrame.isFBComposed[j] = false;
902
903 bool result = postHeuristicsHandling(ctx, list);
904
905 // Restore layer attributes
906 for (int i = 0; i < overlapIdx; i++) {
907 hwc_layer_1_t* layer = &list->hwLayers[i];
908 layer->displayFrame = displayFrame[i];
909 layer->sourceCropf.left = (float)sourceCrop[i].left;
910 layer->sourceCropf.top = (float)sourceCrop[i].top;
911 layer->sourceCropf.right = (float)sourceCrop[i].right;
912 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
913 }
914
915 if (!result) {
916 mOverlapIndex = -1;
917 reset(ctx);
918 }
919
920 ALOGD_IF(isDebug(), "%s: Postheuristics %s!, Overlap index = %d",
921 __FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
922 return result;
923}
924
Saurabh Shahaa236822013-04-24 18:07:26 -0700925bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
926{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700927 if(!sEnableMixedMode) {
928 //Mixed mode is disabled. No need to even try caching.
929 return false;
930 }
931
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700932 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800933 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800934 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800935 cacheBasedComp(ctx, list);
936 } else {
937 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800938 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700939 }
940
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700941 return ret;
942}
943
944bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
945 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700946 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
947 return false;
948
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700949 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700950 mCurrentFrame.reset(numAppLayers);
951 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700952
953 //If an MDP marked layer is unsupported cannot do partial MDP Comp
954 for(int i = 0; i < numAppLayers; i++) {
955 if(!mCurrentFrame.isFBComposed[i]) {
956 hwc_layer_1_t* layer = &list->hwLayers[i];
957 if(not isSupportedForMDPComp(ctx, layer)) {
958 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
959 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800960 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700961 return false;
962 }
963 }
964 }
965
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700966 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530967 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700968 if(!ret) {
969 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800970 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700971 return false;
972 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700973
974 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700975
radhakrishnac9a67412013-09-25 17:40:42 +0530976 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800977 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530978 }
979
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700980 //Will benefit cases where a video has non-updating background.
981 if((mDpy > HWC_DISPLAY_PRIMARY) and
982 (mdpCount > MAX_SEC_LAYERS)) {
983 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800984 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700985 return false;
986 }
987
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800988 if(!postHeuristicsHandling(ctx, list)) {
989 ALOGD_IF(isDebug(), "post heuristic handling failed");
990 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700991 return false;
992 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700993 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
994 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700995
Saurabh Shahaa236822013-04-24 18:07:26 -0700996 return true;
997}
998
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800999bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001000 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001001 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1002 return false;
1003
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001004 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001005 return false;
1006 }
1007
Saurabh Shahb772ae32013-11-18 15:40:02 -08001008 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001009 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1010 const int stagesForMDP = min(sMaxPipesPerMixer,
1011 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001012
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001013 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1014 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1015 int lastMDPSupportedIndex = numAppLayers;
1016 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001017
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001018 //Find the minimum MDP batch size
1019 for(int i = 0; i < numAppLayers;i++) {
1020 if(mCurrentFrame.drop[i]) {
1021 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001022 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001023 }
1024 hwc_layer_1_t* layer = &list->hwLayers[i];
1025 if(not isSupportedForMDPComp(ctx, layer)) {
1026 lastMDPSupportedIndex = i;
1027 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1028 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001029 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001030 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001031 }
1032
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001033 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1034 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1035 mCurrentFrame.dropCount);
1036
1037 //Start at a point where the fb batch should at least have 2 layers, for
1038 //this mode to be justified.
1039 while(fbBatchSize < 2) {
1040 ++fbBatchSize;
1041 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001042 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001043
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001044 //If there are no layers for MDP, this mode doesnt make sense.
1045 if(mdpBatchSize < 1) {
1046 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1047 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001048 return false;
1049 }
1050
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001051 mCurrentFrame.reset(numAppLayers);
1052
1053 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1054 while(mdpBatchSize > 0) {
1055 //Mark layers for MDP comp
1056 int mdpBatchLeft = mdpBatchSize;
1057 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1058 if(mCurrentFrame.drop[i]) {
1059 continue;
1060 }
1061 mCurrentFrame.isFBComposed[i] = false;
1062 --mdpBatchLeft;
1063 }
1064
1065 mCurrentFrame.fbZ = mdpBatchSize;
1066 mCurrentFrame.fbCount = fbBatchSize;
1067 mCurrentFrame.mdpCount = mdpBatchSize;
1068
1069 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1070 __FUNCTION__, mdpBatchSize, fbBatchSize,
1071 mCurrentFrame.dropCount);
1072
1073 if(postHeuristicsHandling(ctx, list)) {
1074 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001075 __FUNCTION__);
1076 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1077 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001078 return true;
1079 }
1080
1081 reset(ctx);
1082 --mdpBatchSize;
1083 ++fbBatchSize;
1084 }
1085
1086 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001087}
1088
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001089bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301090 if(mDpy or isSecurePresent(ctx, mDpy) or
1091 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001092 return false;
1093 }
1094 return true;
1095}
1096
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001097bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1098 hwc_display_contents_1_t* list){
1099 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1100 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1101 mDpy ) {
1102 return false;
1103 }
1104 return true;
1105}
1106
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001107bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1108 hwc_display_contents_1_t* list) {
1109 const bool secureOnly = true;
1110 return videoOnlyComp(ctx, list, not secureOnly) or
1111 videoOnlyComp(ctx, list, secureOnly);
1112}
1113
1114bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001115 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001116 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1117 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001118 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001119
Saurabh Shahaa236822013-04-24 18:07:26 -07001120 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001121 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001122 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001123 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001124
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001125 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1126 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001127 return false;
1128 }
1129
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001130 /* Bail out if we are processing only secured video layers
1131 * and we dont have any */
1132 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001133 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001134 return false;
1135 }
1136
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001137 if(mCurrentFrame.fbCount)
1138 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001139
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001140 if(sEnable4k2kYUVSplit){
1141 adjustForSourceSplit(ctx, list);
1142 }
1143
1144 if(!postHeuristicsHandling(ctx, list)) {
1145 ALOGD_IF(isDebug(), "post heuristic handling failed");
1146 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001147 return false;
1148 }
1149
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001150 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1151 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001152 return true;
1153}
1154
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001155/* Checks for conditions where YUV layers cannot be bypassed */
1156bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001157 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001158 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001159 return false;
1160 }
1161
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001162 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001163 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1164 return false;
1165 }
1166
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001167 if(isSecuring(ctx, layer)) {
1168 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1169 return false;
1170 }
1171
Saurabh Shah4fdde762013-04-30 18:47:33 -07001172 if(!isValidDimension(ctx, layer)) {
1173 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1174 __FUNCTION__);
1175 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001176 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001177
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001178 if(layer->planeAlpha < 0xFF) {
1179 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1180 in video only mode",
1181 __FUNCTION__);
1182 return false;
1183 }
1184
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001185 return true;
1186}
1187
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301188/* starts at fromIndex and check for each layer to find
1189 * if it it has overlapping with any Updating layer above it in zorder
1190 * till the end of the batch. returns true if it finds any intersection */
1191bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1192 int fromIndex, int toIndex) {
1193 for(int i = fromIndex; i < toIndex; i++) {
1194 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1195 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1196 return false;
1197 }
1198 }
1199 }
1200 return true;
1201}
1202
1203/* Checks if given layer at targetLayerIndex has any
1204 * intersection with all the updating layers in beween
1205 * fromIndex and toIndex. Returns true if it finds intersectiion */
1206bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1207 int fromIndex, int toIndex, int targetLayerIndex) {
1208 for(int i = fromIndex; i <= toIndex; i++) {
1209 if(!mCurrentFrame.isFBComposed[i]) {
1210 if(areLayersIntersecting(&list->hwLayers[i],
1211 &list->hwLayers[targetLayerIndex])) {
1212 return true;
1213 }
1214 }
1215 }
1216 return false;
1217}
1218
1219int MDPComp::getBatch(hwc_display_contents_1_t* list,
1220 int& maxBatchStart, int& maxBatchEnd,
1221 int& maxBatchCount) {
1222 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301223 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001224 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301225 while (i < mCurrentFrame.layerCount) {
1226 int batchCount = 0;
1227 int batchStart = i;
1228 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001229 /* Adjust batch Z order with the dropped layers so far */
1230 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301231 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301232 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301233 while(i < mCurrentFrame.layerCount) {
1234 if(!mCurrentFrame.isFBComposed[i]) {
1235 if(!batchCount) {
1236 i++;
1237 break;
1238 }
1239 updatingLayersAbove++;
1240 i++;
1241 continue;
1242 } else {
1243 if(mCurrentFrame.drop[i]) {
1244 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001245 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301246 continue;
1247 } else if(updatingLayersAbove <= 0) {
1248 batchCount++;
1249 batchEnd = i;
1250 i++;
1251 continue;
1252 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1253
1254 // We have a valid updating layer already. If layer-i not
1255 // have overlapping with all updating layers in between
1256 // batch-start and i, then we can add layer i to batch.
1257 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1258 batchCount++;
1259 batchEnd = i;
1260 i++;
1261 continue;
1262 } else if(canPushBatchToTop(list, batchStart, i)) {
1263 //If All the non-updating layers with in this batch
1264 //does not have intersection with the updating layers
1265 //above in z-order, then we can safely move the batch to
1266 //higher z-order. Increment fbZ as it is moving up.
1267 if( firstZReverseIndex < 0) {
1268 firstZReverseIndex = i;
1269 }
1270 batchCount++;
1271 batchEnd = i;
1272 fbZ += updatingLayersAbove;
1273 i++;
1274 updatingLayersAbove = 0;
1275 continue;
1276 } else {
1277 //both failed.start the loop again from here.
1278 if(firstZReverseIndex >= 0) {
1279 i = firstZReverseIndex;
1280 }
1281 break;
1282 }
1283 }
1284 }
1285 }
1286 if(batchCount > maxBatchCount) {
1287 maxBatchCount = batchCount;
1288 maxBatchStart = batchStart;
1289 maxBatchEnd = batchEnd;
1290 fbZOrder = fbZ;
1291 }
1292 }
1293 return fbZOrder;
1294}
1295
1296bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1297 hwc_display_contents_1_t* list) {
1298 /* Idea is to keep as many non-updating(cached) layers in FB and
1299 * send rest of them through MDP. This is done in 2 steps.
1300 * 1. Find the maximum contiguous batch of non-updating layers.
1301 * 2. See if we can improve this batch size for caching by adding
1302 * opaque layers around the batch, if they don't have
1303 * any overlapping with the updating layers in between.
1304 * NEVER mark an updating layer for caching.
1305 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001306
1307 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001308 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001309 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301310 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001311
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001312 /* Nothing is cached. No batching needed */
1313 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001314 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001315 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001316
1317 /* No MDP comp layers, try to use other comp modes */
1318 if(mCurrentFrame.mdpCount == 0) {
1319 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001320 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001321
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301322 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001323
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301324 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001325 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001326 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001327 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301328 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001329 if(!mCurrentFrame.drop[i]){
1330 //If an unsupported layer is being attempted to
1331 //be pulled out we should fail
1332 if(not isSupportedForMDPComp(ctx, layer)) {
1333 return false;
1334 }
1335 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001336 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001337 }
1338 }
1339
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301340 // update the frame data
1341 mCurrentFrame.fbZ = fbZ;
1342 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001343 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001344 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001345
1346 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301347 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001348
1349 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001350}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001351
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001352void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001353 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001354 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001355 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001356
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001357 for(int i = 0; i < numAppLayers; i++) {
1358 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001359 if(!mCurrentFrame.drop[i])
1360 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001361 mCurrentFrame.isFBComposed[i] = true;
1362 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001363 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001364 }
1365 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001366
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001367 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001368 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1369 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001370
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001371 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1372 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1373 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001374}
1375
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001376void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1377 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001378 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1379 for(int index = 0;index < nYuvCount; index++){
1380 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1381 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1382
1383 if(!isYUVDoable(ctx, layer)) {
1384 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1385 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1386 mCurrentFrame.fbCount++;
1387 }
1388 } else {
1389 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001390 private_handle_t *hnd = (private_handle_t *)layer->handle;
1391 if(!secureOnly || isSecureBuffer(hnd)) {
1392 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1393 mCurrentFrame.fbCount--;
1394 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001395 }
1396 }
1397 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001398
1399 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001400 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1401 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001402 mCurrentFrame.fbCount);
1403}
1404
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001405hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1406 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001407 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001408
1409 /* Update only the region of FB needed for composition */
1410 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1411 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1412 hwc_layer_1_t* layer = &list->hwLayers[i];
1413 hwc_rect_t dst = layer->displayFrame;
1414 fbRect = getUnion(fbRect, dst);
1415 }
1416 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001417 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001418 return fbRect;
1419}
1420
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001421bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1422 hwc_display_contents_1_t* list) {
1423
1424 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001425 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001426 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1427 return false;
1428 }
1429
1430 //Limitations checks
1431 if(!hwLimitationsCheck(ctx, list)) {
1432 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1433 return false;
1434 }
1435
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001436 //Configure framebuffer first if applicable
1437 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001438 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001439 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1440 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001441 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1442 __FUNCTION__);
1443 return false;
1444 }
1445 }
1446
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001447 mCurrentFrame.map();
1448
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001449 if(!allocLayerPipes(ctx, list)) {
1450 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001451 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001452 }
1453
1454 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001455 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001456 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001457 int mdpIndex = mCurrentFrame.layerToMDP[index];
1458 hwc_layer_1_t* layer = &list->hwLayers[index];
1459
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301460 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1461 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1462 mdpNextZOrder++;
1463 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001464 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1465 cur_pipe->zOrder = mdpNextZOrder++;
1466
radhakrishnac9a67412013-09-25 17:40:42 +05301467 private_handle_t *hnd = (private_handle_t *)layer->handle;
1468 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1469 if(configure4k2kYuv(ctx, layer,
1470 mCurrentFrame.mdpToLayer[mdpIndex])
1471 != 0 ){
1472 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1473 for layer %d",__FUNCTION__, index);
1474 return false;
1475 }
1476 else{
1477 mdpNextZOrder++;
1478 }
1479 continue;
1480 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001481 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1482 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301483 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001484 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001485 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001486 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001487 }
1488
Saurabh Shaha36be922013-12-16 18:18:39 -08001489 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1490 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1491 ,__FUNCTION__, mDpy);
1492 return false;
1493 }
1494
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001495 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001496 return true;
1497}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001498
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001499bool MDPComp::resourceCheck(hwc_context_t* ctx,
1500 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001501 const bool fbUsed = mCurrentFrame.fbCount;
1502 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1503 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1504 return false;
1505 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001506 // Init rotCount to number of rotate sessions used by other displays
1507 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1508 // Count the number of rotator sessions required for current display
1509 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1510 if(!mCurrentFrame.isFBComposed[index]) {
1511 hwc_layer_1_t* layer = &list->hwLayers[index];
1512 private_handle_t *hnd = (private_handle_t *)layer->handle;
1513 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1514 rotCount++;
1515 }
1516 }
1517 }
1518 // if number of layers to rotate exceeds max rotator sessions, bail out.
1519 if(rotCount > RotMgr::MAX_ROT_SESS) {
1520 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1521 __FUNCTION__, mDpy);
1522 return false;
1523 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001524 return true;
1525}
1526
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301527bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1528 hwc_display_contents_1_t* list) {
1529
1530 //A-family hw limitation:
1531 //If a layer need alpha scaling, MDP can not support.
1532 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1533 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1534 if(!mCurrentFrame.isFBComposed[i] &&
1535 isAlphaScaled( &list->hwLayers[i])) {
1536 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1537 return false;
1538 }
1539 }
1540 }
1541
1542 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1543 //If multiple layers requires downscaling and also they are overlapping
1544 //fall back to GPU since MDSS can not handle it.
1545 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1546 qdutils::MDPVersion::getInstance().is8x26()) {
1547 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1548 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1549 if(!mCurrentFrame.isFBComposed[i] &&
1550 isDownscaleRequired(botLayer)) {
1551 //if layer-i is marked for MDP and needs downscaling
1552 //check if any MDP layer on top of i & overlaps with layer-i
1553 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1554 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1555 if(!mCurrentFrame.isFBComposed[j] &&
1556 isDownscaleRequired(topLayer)) {
1557 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1558 topLayer->displayFrame);
1559 if(isValidRect(r))
1560 return false;
1561 }
1562 }
1563 }
1564 }
1565 }
1566 return true;
1567}
1568
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001569int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001570 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001571 char property[PROPERTY_VALUE_MAX];
1572
Raj Kamal4393eaa2014-06-06 13:45:20 +05301573 if(!ctx || !list) {
1574 ALOGE("%s: Invalid context or list",__FUNCTION__);
1575 mCachedFrame.reset();
1576 return -1;
1577 }
1578
1579 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1580
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001581 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1582 int currentFlags = atoi(property);
1583 if(currentFlags != sSimulationFlags) {
1584 sSimulationFlags = currentFlags;
1585 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1586 sSimulationFlags, sSimulationFlags);
1587 }
1588 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001589 mOverlapIndex = -1;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001590
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301591 //Do not cache the information for next draw cycle.
1592 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1593 ALOGI("%s: Unsupported layer count for mdp composition",
1594 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001595 mCachedFrame.reset();
1596 return -1;
1597 }
1598
Saurabh Shahb39f8152013-08-22 10:21:44 -07001599 //reset old data
1600 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001601 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1602 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301603
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001604 // Detect the start of animation and fall back to GPU only once to cache
1605 // all the layers in FB and display FB content untill animation completes.
1606 if(ctx->listStats[mDpy].isDisplayAnimating) {
1607 mCurrentFrame.needsRedraw = false;
1608 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1609 mCurrentFrame.needsRedraw = true;
1610 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1611 }
1612 setMDPCompLayerFlags(ctx, list);
1613 mCachedFrame.updateCounts(mCurrentFrame);
1614 ret = -1;
1615 return ret;
1616 } else {
1617 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1618 }
1619
Saurabh Shahb39f8152013-08-22 10:21:44 -07001620 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001621 if(isFrameDoable(ctx)) {
1622 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001623
Raj Kamal4393eaa2014-06-06 13:45:20 +05301624 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1625 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001626 setMDPCompLayerFlags(ctx, list);
1627 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001628 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001629 reset(ctx);
1630 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1631 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001632 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001633 }
1634 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001635 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1636 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001637 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001638 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001639
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001640 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001641 ALOGD("GEOMETRY change: %d",
1642 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001644 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001645 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001646 }
1647
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001648 mCachedFrame.cacheAll(list);
1649 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001650 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001651}
1652
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001653bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301654
1655 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301656 int mdpIndex = mCurrentFrame.layerToMDP[index];
1657 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1658 info.pipeInfo = new MdpYUVPipeInfo;
1659 info.rot = NULL;
1660 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301661
1662 pipe_info.lIndex = ovutils::OV_INVALID;
1663 pipe_info.rIndex = ovutils::OV_INVALID;
1664
Saurabh Shahc62f3982014-03-05 14:28:26 -08001665 Overlay::PipeSpecs pipeSpecs;
1666 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1667 pipeSpecs.needsScaling = true;
1668 pipeSpecs.dpy = mDpy;
1669 pipeSpecs.fb = false;
1670
1671 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301672 if(pipe_info.lIndex == ovutils::OV_INVALID){
1673 bRet = false;
1674 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1675 __FUNCTION__);
1676 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001677 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301678 if(pipe_info.rIndex == ovutils::OV_INVALID){
1679 bRet = false;
1680 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1681 __FUNCTION__);
1682 }
1683 return bRet;
1684}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001685
1686int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1687 int fd = -1;
1688 if (mOverlapIndex != -1) {
1689 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
1690 if (fd < 0) {
1691 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
1692 mOverlapIndex = -1;
1693 }
1694 }
1695 return fd;
1696}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001697//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001698
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001699void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301700 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001701 //If 4k2k Yuv layer split is possible, and if
1702 //fbz is above 4k2k layer, increment fb zorder by 1
1703 //as we split 4k2k layer and increment zorder for right half
1704 //of the layer
1705 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301706 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1707 index++) {
1708 if(!mCurrentFrame.isFBComposed[index]) {
1709 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1710 mdpNextZOrder++;
1711 }
1712 mdpNextZOrder++;
1713 hwc_layer_1_t* layer = &list->hwLayers[index];
1714 private_handle_t *hnd = (private_handle_t *)layer->handle;
1715 if(is4kx2kYuvBuffer(hnd)) {
1716 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1717 mCurrentFrame.fbZ += 1;
1718 mdpNextZOrder++;
1719 //As we split 4kx2k yuv layer and program to 2 VG pipes
1720 //(if available) increase mdpcount by 1.
1721 mCurrentFrame.mdpCount++;
1722 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001723 }
1724 }
1725 }
radhakrishnac9a67412013-09-25 17:40:42 +05301726}
1727
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001728/*
1729 * Configures pipe(s) for MDP composition
1730 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001731int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001732 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001733 MdpPipeInfoNonSplit& mdp_info =
1734 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001735 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1736 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1737 eIsFg isFg = IS_FG_OFF;
1738 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001739
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001740 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1741 __FUNCTION__, layer, zOrder, dest);
1742
Saurabh Shah88e4d272013-09-03 13:31:29 -07001743 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001744 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001745}
1746
Saurabh Shah88e4d272013-09-03 13:31:29 -07001747bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001748 hwc_display_contents_1_t* list) {
1749 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001750
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001751 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001752
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001753 hwc_layer_1_t* layer = &list->hwLayers[index];
1754 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301755 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001756 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301757 continue;
1758 }
1759 }
1760
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001761 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001762 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001763 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001764 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001765 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001766
Saurabh Shahc62f3982014-03-05 14:28:26 -08001767 Overlay::PipeSpecs pipeSpecs;
1768 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1769 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1770 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1771 (qdutils::MDPVersion::getInstance().is8x26() and
1772 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1773 pipeSpecs.dpy = mDpy;
1774 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001775 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001776
Saurabh Shahc62f3982014-03-05 14:28:26 -08001777 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1778
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001779 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001780 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001781 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001782 }
1783 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001784 return true;
1785}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001786
radhakrishnac9a67412013-09-25 17:40:42 +05301787int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1788 PipeLayerPair& PipeLayerPair) {
1789 MdpYUVPipeInfo& mdp_info =
1790 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1791 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1792 eIsFg isFg = IS_FG_OFF;
1793 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1794 eDest lDest = mdp_info.lIndex;
1795 eDest rDest = mdp_info.rIndex;
1796
1797 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1798 lDest, rDest, &PipeLayerPair.rot);
1799}
1800
Saurabh Shah88e4d272013-09-03 13:31:29 -07001801bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001802
Raj Kamal4393eaa2014-06-06 13:45:20 +05301803 if(!isEnabled() or !mModeOn) {
1804 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301805 return true;
1806 }
1807
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001808 // Set the Handle timeout to true for MDP or MIXED composition.
1809 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1810 sHandleTimeout = true;
1811 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001812
1813 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001815
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001816 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1817 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001818 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001819 if(mCurrentFrame.isFBComposed[i]) continue;
1820
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001821 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001822 private_handle_t *hnd = (private_handle_t *)layer->handle;
1823 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001824 if (!(layer->flags & HWC_COLOR_FILL)) {
1825 ALOGE("%s handle null", __FUNCTION__);
1826 return false;
1827 }
1828 // No PLAY for Color layer
1829 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1830 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001831 }
1832
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001833 int mdpIndex = mCurrentFrame.layerToMDP[i];
1834
radhakrishnac9a67412013-09-25 17:40:42 +05301835 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1836 {
1837 MdpYUVPipeInfo& pipe_info =
1838 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1839 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1840 ovutils::eDest indexL = pipe_info.lIndex;
1841 ovutils::eDest indexR = pipe_info.rIndex;
1842 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301843 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301844 if(rot) {
1845 rot->queueBuffer(fd, offset);
1846 fd = rot->getDstMemId();
1847 offset = rot->getDstOffset();
1848 }
1849 if(indexL != ovutils::OV_INVALID) {
1850 ovutils::eDest destL = (ovutils::eDest)indexL;
1851 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1852 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1853 if (!ov.queueBuffer(fd, offset, destL)) {
1854 ALOGE("%s: queueBuffer failed for display:%d",
1855 __FUNCTION__, mDpy);
1856 return false;
1857 }
1858 }
1859
1860 if(indexR != ovutils::OV_INVALID) {
1861 ovutils::eDest destR = (ovutils::eDest)indexR;
1862 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1863 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1864 if (!ov.queueBuffer(fd, offset, destR)) {
1865 ALOGE("%s: queueBuffer failed for display:%d",
1866 __FUNCTION__, mDpy);
1867 return false;
1868 }
1869 }
1870 }
1871 else{
1872 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001873 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301874 ovutils::eDest dest = pipe_info.index;
1875 if(dest == ovutils::OV_INVALID) {
1876 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001877 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301878 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001879
radhakrishnac9a67412013-09-25 17:40:42 +05301880 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1881 continue;
1882 }
1883
Sushil Chauhandefd3522014-05-13 18:17:12 -07001884 if (!mDpy && (i == mOverlapIndex)) {
1885 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1886 }
1887
radhakrishnac9a67412013-09-25 17:40:42 +05301888 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1889 using pipe: %d", __FUNCTION__, layer,
1890 hnd, dest );
1891
1892 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301893 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301894
1895 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1896 if(rot) {
1897 if(!rot->queueBuffer(fd, offset))
1898 return false;
1899 fd = rot->getDstMemId();
1900 offset = rot->getDstOffset();
1901 }
1902
1903 if (!ov.queueBuffer(fd, offset, dest)) {
1904 ALOGE("%s: queueBuffer failed for display:%d ",
1905 __FUNCTION__, mDpy);
1906 return false;
1907 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001908 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001909
1910 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001911 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001912 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001913}
1914
Saurabh Shah88e4d272013-09-03 13:31:29 -07001915//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001916
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001917void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301918 hwc_display_contents_1_t* list){
1919 //if 4kx2k yuv layer is totally present in either in left half
1920 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301921 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301922 if(mCurrentFrame.fbZ >= 0) {
1923 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1924 index++) {
1925 if(!mCurrentFrame.isFBComposed[index]) {
1926 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1927 mdpNextZOrder++;
1928 }
1929 mdpNextZOrder++;
1930 hwc_layer_1_t* layer = &list->hwLayers[index];
1931 private_handle_t *hnd = (private_handle_t *)layer->handle;
1932 if(is4kx2kYuvBuffer(hnd)) {
1933 hwc_rect_t dst = layer->displayFrame;
1934 if((dst.left > lSplit) || (dst.right < lSplit)) {
1935 mCurrentFrame.mdpCount += 1;
1936 }
1937 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1938 mCurrentFrame.fbZ += 1;
1939 mdpNextZOrder++;
1940 }
1941 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001942 }
radhakrishnac9a67412013-09-25 17:40:42 +05301943 }
1944}
1945
Saurabh Shah88e4d272013-09-03 13:31:29 -07001946bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001947 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001948
Saurabh Shahc62f3982014-03-05 14:28:26 -08001949 const int lSplit = getLeftSplit(ctx, mDpy);
1950 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001951 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001952 pipe_info.lIndex = ovutils::OV_INVALID;
1953 pipe_info.rIndex = ovutils::OV_INVALID;
1954
Saurabh Shahc62f3982014-03-05 14:28:26 -08001955 Overlay::PipeSpecs pipeSpecs;
1956 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1957 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1958 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
1959 pipeSpecs.dpy = mDpy;
1960 pipeSpecs.mixer = Overlay::MIXER_LEFT;
1961 pipeSpecs.fb = false;
1962
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001963 // Acquire pipe only for the updating half
1964 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
1965 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
1966
1967 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001968 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001969 if(pipe_info.lIndex == ovutils::OV_INVALID)
1970 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001971 }
1972
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001973 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001974 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
1975 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001976 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001977 return false;
1978 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001979
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001980 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001981}
1982
Saurabh Shah88e4d272013-09-03 13:31:29 -07001983bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001984 hwc_display_contents_1_t* list) {
1985 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001986
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001987 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001988
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001989 hwc_layer_1_t* layer = &list->hwLayers[index];
1990 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301991 hwc_rect_t dst = layer->displayFrame;
1992 const int lSplit = getLeftSplit(ctx, mDpy);
1993 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1994 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001995 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301996 continue;
1997 }
1998 }
1999 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002000 int mdpIndex = mCurrentFrame.layerToMDP[index];
2001 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002002 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002003 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002004 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002005
Saurabh Shahc62f3982014-03-05 14:28:26 -08002006 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2007 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2008 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002009 return false;
2010 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002011 }
2012 return true;
2013}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002014
radhakrishnac9a67412013-09-25 17:40:42 +05302015int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2016 PipeLayerPair& PipeLayerPair) {
2017 const int lSplit = getLeftSplit(ctx, mDpy);
2018 hwc_rect_t dst = layer->displayFrame;
2019 if((dst.left > lSplit)||(dst.right < lSplit)){
2020 MdpYUVPipeInfo& mdp_info =
2021 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2022 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2023 eIsFg isFg = IS_FG_OFF;
2024 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2025 eDest lDest = mdp_info.lIndex;
2026 eDest rDest = mdp_info.rIndex;
2027
2028 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2029 lDest, rDest, &PipeLayerPair.rot);
2030 }
2031 else{
2032 return configure(ctx, layer, PipeLayerPair);
2033 }
2034}
2035
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002036/*
2037 * Configures pipe(s) for MDP composition
2038 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002039int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002040 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002041 MdpPipeInfoSplit& mdp_info =
2042 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002043 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2044 eIsFg isFg = IS_FG_OFF;
2045 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2046 eDest lDest = mdp_info.lIndex;
2047 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002048
2049 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2050 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2051
Saurabh Shah88e4d272013-09-03 13:31:29 -07002052 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002053 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002054}
2055
Saurabh Shah88e4d272013-09-03 13:31:29 -07002056bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002057
Raj Kamal4393eaa2014-06-06 13:45:20 +05302058 if(!isEnabled() or !mModeOn) {
2059 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302060 return true;
2061 }
2062
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002063 // Set the Handle timeout to true for MDP or MIXED composition.
2064 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2065 sHandleTimeout = true;
2066 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002067
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002068 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002069 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002070
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002071 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2072 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002073 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002074 if(mCurrentFrame.isFBComposed[i]) continue;
2075
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002076 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002077 private_handle_t *hnd = (private_handle_t *)layer->handle;
2078 if(!hnd) {
2079 ALOGE("%s handle null", __FUNCTION__);
2080 return false;
2081 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002082
2083 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2084 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002085 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002086
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002087 int mdpIndex = mCurrentFrame.layerToMDP[i];
2088
radhakrishnac9a67412013-09-25 17:40:42 +05302089 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2090 {
2091 MdpYUVPipeInfo& pipe_info =
2092 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2093 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2094 ovutils::eDest indexL = pipe_info.lIndex;
2095 ovutils::eDest indexR = pipe_info.rIndex;
2096 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302097 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302098 if(rot) {
2099 rot->queueBuffer(fd, offset);
2100 fd = rot->getDstMemId();
2101 offset = rot->getDstOffset();
2102 }
2103 if(indexL != ovutils::OV_INVALID) {
2104 ovutils::eDest destL = (ovutils::eDest)indexL;
2105 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2106 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2107 if (!ov.queueBuffer(fd, offset, destL)) {
2108 ALOGE("%s: queueBuffer failed for display:%d",
2109 __FUNCTION__, mDpy);
2110 return false;
2111 }
2112 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002113
radhakrishnac9a67412013-09-25 17:40:42 +05302114 if(indexR != ovutils::OV_INVALID) {
2115 ovutils::eDest destR = (ovutils::eDest)indexR;
2116 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2117 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2118 if (!ov.queueBuffer(fd, offset, destR)) {
2119 ALOGE("%s: queueBuffer failed for display:%d",
2120 __FUNCTION__, mDpy);
2121 return false;
2122 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002123 }
2124 }
radhakrishnac9a67412013-09-25 17:40:42 +05302125 else{
2126 MdpPipeInfoSplit& pipe_info =
2127 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2128 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002129
radhakrishnac9a67412013-09-25 17:40:42 +05302130 ovutils::eDest indexL = pipe_info.lIndex;
2131 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002132
Sushil Chauhandefd3522014-05-13 18:17:12 -07002133 if (!mDpy && (i == mOverlapIndex)) {
2134 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2135 }
2136
radhakrishnac9a67412013-09-25 17:40:42 +05302137 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302138 int offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302139
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002140 if(ctx->mAD->draw(ctx, fd, offset)) {
2141 fd = ctx->mAD->getDstFd();
2142 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002143 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002144
radhakrishnac9a67412013-09-25 17:40:42 +05302145 if(rot) {
2146 rot->queueBuffer(fd, offset);
2147 fd = rot->getDstMemId();
2148 offset = rot->getDstOffset();
2149 }
2150
2151 //************* play left mixer **********
2152 if(indexL != ovutils::OV_INVALID) {
2153 ovutils::eDest destL = (ovutils::eDest)indexL;
2154 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2155 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2156 if (!ov.queueBuffer(fd, offset, destL)) {
2157 ALOGE("%s: queueBuffer failed for left mixer",
2158 __FUNCTION__);
2159 return false;
2160 }
2161 }
2162
2163 //************* play right mixer **********
2164 if(indexR != ovutils::OV_INVALID) {
2165 ovutils::eDest destR = (ovutils::eDest)indexR;
2166 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2167 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2168 if (!ov.queueBuffer(fd, offset, destR)) {
2169 ALOGE("%s: queueBuffer failed for right mixer",
2170 __FUNCTION__);
2171 return false;
2172 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002173 }
2174 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002175
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002176 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2177 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002178
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002179 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002180}
Saurabh Shahab47c692014-02-12 18:45:57 -08002181
2182//================MDPCompSrcSplit==============================================
2183bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002184 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002185 private_handle_t *hnd = (private_handle_t *)layer->handle;
2186 hwc_rect_t dst = layer->displayFrame;
2187 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2188 pipe_info.lIndex = ovutils::OV_INVALID;
2189 pipe_info.rIndex = ovutils::OV_INVALID;
2190
2191 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2192 //should have a higher priority than the right one. Pipe priorities are
2193 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002194
Saurabh Shahc62f3982014-03-05 14:28:26 -08002195 Overlay::PipeSpecs pipeSpecs;
2196 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2197 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2198 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2199 pipeSpecs.dpy = mDpy;
2200 pipeSpecs.fb = false;
2201
Saurabh Shahab47c692014-02-12 18:45:57 -08002202 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002203 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002204 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002205 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002206 }
2207
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002208 /* Use 2 pipes IF
2209 a) Layer's crop width is > 2048 or
2210 b) Layer's dest width > 2048 or
2211 c) On primary, driver has indicated with caps to split always. This is
2212 based on an empirically derived value of panel height. Applied only
2213 if the layer's width is > mixer's width
2214 */
2215
2216 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2217 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2218 int lSplit = getLeftSplit(ctx, mDpy);
2219 int dstWidth = dst.right - dst.left;
2220 int cropWidth = crop.right - crop.left;
2221
2222 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2223 cropWidth > qdutils::MAX_DISPLAY_DIM or
2224 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002225 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002226 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002227 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002228 }
2229
2230 // Return values
2231 // 1 Left pipe is higher priority, do nothing.
2232 // 0 Pipes of same priority.
2233 //-1 Right pipe is of higher priority, needs swap.
2234 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2235 pipe_info.rIndex) == -1) {
2236 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002237 }
2238 }
2239
2240 return true;
2241}
2242
Saurabh Shahab47c692014-02-12 18:45:57 -08002243int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2244 PipeLayerPair& PipeLayerPair) {
2245 private_handle_t *hnd = (private_handle_t *)layer->handle;
2246 if(!hnd) {
2247 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2248 return -1;
2249 }
2250 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2251 MdpPipeInfoSplit& mdp_info =
2252 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2253 Rotator **rot = &PipeLayerPair.rot;
2254 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2255 eIsFg isFg = IS_FG_OFF;
2256 eDest lDest = mdp_info.lIndex;
2257 eDest rDest = mdp_info.rIndex;
2258 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2259 hwc_rect_t dst = layer->displayFrame;
2260 int transform = layer->transform;
2261 eTransform orient = static_cast<eTransform>(transform);
2262 const int downscale = 0;
2263 int rotFlags = ROT_FLAGS_NONE;
2264 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2265 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2266
2267 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2268 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2269
2270 // Handle R/B swap
2271 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2272 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2273 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2274 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2275 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2276 }
2277
Saurabh Shah97e2d802014-04-14 18:03:54 -07002278 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002279 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002280
2281 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2282 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002283 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002284 }
2285
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002286 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002287 (*rot) = ctx->mRotMgr->getNext();
2288 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002289 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002290 //If the video is using a single pipe, enable BWC
2291 if(rDest == OV_INVALID) {
2292 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2293 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002294 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002295 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002296 ALOGE("%s: configRotator failed!", __FUNCTION__);
2297 return -1;
2298 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002299 whf.format = (*rot)->getDstFormat();
2300 updateSource(orient, whf, crop);
2301 rotFlags |= ROT_PREROTATED;
2302 }
2303
2304 //If 2 pipes being used, divide layer into half, crop and dst
2305 hwc_rect_t cropL = crop;
2306 hwc_rect_t cropR = crop;
2307 hwc_rect_t dstL = dst;
2308 hwc_rect_t dstR = dst;
2309 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2310 cropL.right = (crop.right + crop.left) / 2;
2311 cropR.left = cropL.right;
2312 sanitizeSourceCrop(cropL, cropR, hnd);
2313
2314 //Swap crops on H flip since 2 pipes are being used
2315 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2316 hwc_rect_t tmp = cropL;
2317 cropL = cropR;
2318 cropR = tmp;
2319 }
2320
2321 dstL.right = (dst.right + dst.left) / 2;
2322 dstR.left = dstL.right;
2323 }
2324
2325 //For the mdp, since either we are pre-rotating or MDP does flips
2326 orient = OVERLAY_TRANSFORM_0;
2327 transform = 0;
2328
2329 //configure left pipe
2330 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002331 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002332 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2333 (ovutils::eBlending) getBlending(layer->blending));
2334
2335 if(configMdp(ctx->mOverlay, pargL, orient,
2336 cropL, dstL, metadata, lDest) < 0) {
2337 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2338 return -1;
2339 }
2340 }
2341
2342 //configure right pipe
2343 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002344 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002345 static_cast<eRotFlags>(rotFlags),
2346 layer->planeAlpha,
2347 (ovutils::eBlending) getBlending(layer->blending));
2348 if(configMdp(ctx->mOverlay, pargR, orient,
2349 cropR, dstR, metadata, rDest) < 0) {
2350 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2351 return -1;
2352 }
2353 }
2354
2355 return 0;
2356}
2357
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002358}; //namespace
2359