blob: 55a6497b3fae01a6158018b0876bdd8bfa73fee0 [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
Shalaj Jaina70b4352014-06-15 13:47:47 -07001705 if(!ctx)
1706 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001707 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301708 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1709 index++) {
1710 if(!mCurrentFrame.isFBComposed[index]) {
1711 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1712 mdpNextZOrder++;
1713 }
1714 mdpNextZOrder++;
1715 hwc_layer_1_t* layer = &list->hwLayers[index];
1716 private_handle_t *hnd = (private_handle_t *)layer->handle;
1717 if(is4kx2kYuvBuffer(hnd)) {
1718 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1719 mCurrentFrame.fbZ += 1;
1720 mdpNextZOrder++;
1721 //As we split 4kx2k yuv layer and program to 2 VG pipes
1722 //(if available) increase mdpcount by 1.
1723 mCurrentFrame.mdpCount++;
1724 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001725 }
1726 }
1727 }
radhakrishnac9a67412013-09-25 17:40:42 +05301728}
1729
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001730/*
1731 * Configures pipe(s) for MDP composition
1732 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001733int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001734 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001735 MdpPipeInfoNonSplit& mdp_info =
1736 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001737 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1738 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1739 eIsFg isFg = IS_FG_OFF;
1740 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001741
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001742 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1743 __FUNCTION__, layer, zOrder, dest);
1744
Saurabh Shah88e4d272013-09-03 13:31:29 -07001745 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001746 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001747}
1748
Saurabh Shah88e4d272013-09-03 13:31:29 -07001749bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001750 hwc_display_contents_1_t* list) {
1751 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001752
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001753 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001754
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001755 hwc_layer_1_t* layer = &list->hwLayers[index];
1756 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301757 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001758 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301759 continue;
1760 }
1761 }
1762
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001763 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001764 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001765 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001766 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001767 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001768
Saurabh Shahc62f3982014-03-05 14:28:26 -08001769 Overlay::PipeSpecs pipeSpecs;
1770 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1771 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1772 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1773 (qdutils::MDPVersion::getInstance().is8x26() and
1774 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1775 pipeSpecs.dpy = mDpy;
1776 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001777 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001778
Saurabh Shahc62f3982014-03-05 14:28:26 -08001779 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1780
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001781 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001782 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001783 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001784 }
1785 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001786 return true;
1787}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001788
radhakrishnac9a67412013-09-25 17:40:42 +05301789int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1790 PipeLayerPair& PipeLayerPair) {
1791 MdpYUVPipeInfo& mdp_info =
1792 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1793 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1794 eIsFg isFg = IS_FG_OFF;
1795 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1796 eDest lDest = mdp_info.lIndex;
1797 eDest rDest = mdp_info.rIndex;
1798
1799 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1800 lDest, rDest, &PipeLayerPair.rot);
1801}
1802
Saurabh Shah88e4d272013-09-03 13:31:29 -07001803bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001804
Raj Kamal4393eaa2014-06-06 13:45:20 +05301805 if(!isEnabled() or !mModeOn) {
1806 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301807 return true;
1808 }
1809
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001810 // Set the Handle timeout to true for MDP or MIXED composition.
1811 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1812 sHandleTimeout = true;
1813 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001814
1815 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001816 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001817
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001818 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1819 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001820 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001821 if(mCurrentFrame.isFBComposed[i]) continue;
1822
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001823 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001824 private_handle_t *hnd = (private_handle_t *)layer->handle;
1825 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001826 if (!(layer->flags & HWC_COLOR_FILL)) {
1827 ALOGE("%s handle null", __FUNCTION__);
1828 return false;
1829 }
1830 // No PLAY for Color layer
1831 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1832 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001833 }
1834
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001835 int mdpIndex = mCurrentFrame.layerToMDP[i];
1836
radhakrishnac9a67412013-09-25 17:40:42 +05301837 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1838 {
1839 MdpYUVPipeInfo& pipe_info =
1840 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1841 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1842 ovutils::eDest indexL = pipe_info.lIndex;
1843 ovutils::eDest indexR = pipe_info.rIndex;
1844 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301845 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301846 if(rot) {
1847 rot->queueBuffer(fd, offset);
1848 fd = rot->getDstMemId();
1849 offset = rot->getDstOffset();
1850 }
1851 if(indexL != ovutils::OV_INVALID) {
1852 ovutils::eDest destL = (ovutils::eDest)indexL;
1853 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1854 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1855 if (!ov.queueBuffer(fd, offset, destL)) {
1856 ALOGE("%s: queueBuffer failed for display:%d",
1857 __FUNCTION__, mDpy);
1858 return false;
1859 }
1860 }
1861
1862 if(indexR != ovutils::OV_INVALID) {
1863 ovutils::eDest destR = (ovutils::eDest)indexR;
1864 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1865 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1866 if (!ov.queueBuffer(fd, offset, destR)) {
1867 ALOGE("%s: queueBuffer failed for display:%d",
1868 __FUNCTION__, mDpy);
1869 return false;
1870 }
1871 }
1872 }
1873 else{
1874 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001875 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301876 ovutils::eDest dest = pipe_info.index;
1877 if(dest == ovutils::OV_INVALID) {
1878 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001879 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301880 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001881
radhakrishnac9a67412013-09-25 17:40:42 +05301882 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1883 continue;
1884 }
1885
Sushil Chauhandefd3522014-05-13 18:17:12 -07001886 if (!mDpy && (i == mOverlapIndex)) {
1887 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1888 }
1889
radhakrishnac9a67412013-09-25 17:40:42 +05301890 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1891 using pipe: %d", __FUNCTION__, layer,
1892 hnd, dest );
1893
1894 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301895 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301896
1897 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1898 if(rot) {
1899 if(!rot->queueBuffer(fd, offset))
1900 return false;
1901 fd = rot->getDstMemId();
1902 offset = rot->getDstOffset();
1903 }
1904
1905 if (!ov.queueBuffer(fd, offset, dest)) {
1906 ALOGE("%s: queueBuffer failed for display:%d ",
1907 __FUNCTION__, mDpy);
1908 return false;
1909 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001910 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001911
1912 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001913 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001914 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001915}
1916
Saurabh Shah88e4d272013-09-03 13:31:29 -07001917//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001918
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001919void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301920 hwc_display_contents_1_t* list){
1921 //if 4kx2k yuv layer is totally present in either in left half
1922 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301923 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301924 if(mCurrentFrame.fbZ >= 0) {
1925 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1926 index++) {
1927 if(!mCurrentFrame.isFBComposed[index]) {
1928 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1929 mdpNextZOrder++;
1930 }
1931 mdpNextZOrder++;
1932 hwc_layer_1_t* layer = &list->hwLayers[index];
1933 private_handle_t *hnd = (private_handle_t *)layer->handle;
1934 if(is4kx2kYuvBuffer(hnd)) {
1935 hwc_rect_t dst = layer->displayFrame;
1936 if((dst.left > lSplit) || (dst.right < lSplit)) {
1937 mCurrentFrame.mdpCount += 1;
1938 }
1939 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1940 mCurrentFrame.fbZ += 1;
1941 mdpNextZOrder++;
1942 }
1943 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001944 }
radhakrishnac9a67412013-09-25 17:40:42 +05301945 }
1946}
1947
Saurabh Shah88e4d272013-09-03 13:31:29 -07001948bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001949 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001950
Saurabh Shahc62f3982014-03-05 14:28:26 -08001951 const int lSplit = getLeftSplit(ctx, mDpy);
1952 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001953 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001954 pipe_info.lIndex = ovutils::OV_INVALID;
1955 pipe_info.rIndex = ovutils::OV_INVALID;
1956
Saurabh Shahc62f3982014-03-05 14:28:26 -08001957 Overlay::PipeSpecs pipeSpecs;
1958 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1959 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1960 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
1961 pipeSpecs.dpy = mDpy;
1962 pipeSpecs.mixer = Overlay::MIXER_LEFT;
1963 pipeSpecs.fb = false;
1964
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001965 // Acquire pipe only for the updating half
1966 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
1967 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
1968
1969 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001970 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001971 if(pipe_info.lIndex == ovutils::OV_INVALID)
1972 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001973 }
1974
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001975 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001976 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
1977 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001978 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001979 return false;
1980 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001981
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001982 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001983}
1984
Saurabh Shah88e4d272013-09-03 13:31:29 -07001985bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001986 hwc_display_contents_1_t* list) {
1987 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001988
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001989 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001990
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001991 hwc_layer_1_t* layer = &list->hwLayers[index];
1992 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301993 hwc_rect_t dst = layer->displayFrame;
1994 const int lSplit = getLeftSplit(ctx, mDpy);
1995 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1996 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001997 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301998 continue;
1999 }
2000 }
2001 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002002 int mdpIndex = mCurrentFrame.layerToMDP[index];
2003 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002004 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002005 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002006 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002007
Saurabh Shahc62f3982014-03-05 14:28:26 -08002008 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2009 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2010 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002011 return false;
2012 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002013 }
2014 return true;
2015}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002016
radhakrishnac9a67412013-09-25 17:40:42 +05302017int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2018 PipeLayerPair& PipeLayerPair) {
2019 const int lSplit = getLeftSplit(ctx, mDpy);
2020 hwc_rect_t dst = layer->displayFrame;
2021 if((dst.left > lSplit)||(dst.right < lSplit)){
2022 MdpYUVPipeInfo& mdp_info =
2023 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2024 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2025 eIsFg isFg = IS_FG_OFF;
2026 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2027 eDest lDest = mdp_info.lIndex;
2028 eDest rDest = mdp_info.rIndex;
2029
2030 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2031 lDest, rDest, &PipeLayerPair.rot);
2032 }
2033 else{
2034 return configure(ctx, layer, PipeLayerPair);
2035 }
2036}
2037
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002038/*
2039 * Configures pipe(s) for MDP composition
2040 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002041int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002042 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002043 MdpPipeInfoSplit& mdp_info =
2044 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002045 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2046 eIsFg isFg = IS_FG_OFF;
2047 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2048 eDest lDest = mdp_info.lIndex;
2049 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002050
2051 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2052 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2053
Saurabh Shah88e4d272013-09-03 13:31:29 -07002054 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002055 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002056}
2057
Saurabh Shah88e4d272013-09-03 13:31:29 -07002058bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002059
Raj Kamal4393eaa2014-06-06 13:45:20 +05302060 if(!isEnabled() or !mModeOn) {
2061 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302062 return true;
2063 }
2064
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002065 // Set the Handle timeout to true for MDP or MIXED composition.
2066 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2067 sHandleTimeout = true;
2068 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002069
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002070 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002071 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002072
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002073 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2074 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002075 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002076 if(mCurrentFrame.isFBComposed[i]) continue;
2077
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002078 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002079 private_handle_t *hnd = (private_handle_t *)layer->handle;
2080 if(!hnd) {
2081 ALOGE("%s handle null", __FUNCTION__);
2082 return false;
2083 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002084
2085 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2086 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002087 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002088
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002089 int mdpIndex = mCurrentFrame.layerToMDP[i];
2090
radhakrishnac9a67412013-09-25 17:40:42 +05302091 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2092 {
2093 MdpYUVPipeInfo& pipe_info =
2094 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2095 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2096 ovutils::eDest indexL = pipe_info.lIndex;
2097 ovutils::eDest indexR = pipe_info.rIndex;
2098 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302099 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302100 if(rot) {
2101 rot->queueBuffer(fd, offset);
2102 fd = rot->getDstMemId();
2103 offset = rot->getDstOffset();
2104 }
2105 if(indexL != ovutils::OV_INVALID) {
2106 ovutils::eDest destL = (ovutils::eDest)indexL;
2107 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2108 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2109 if (!ov.queueBuffer(fd, offset, destL)) {
2110 ALOGE("%s: queueBuffer failed for display:%d",
2111 __FUNCTION__, mDpy);
2112 return false;
2113 }
2114 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002115
radhakrishnac9a67412013-09-25 17:40:42 +05302116 if(indexR != ovutils::OV_INVALID) {
2117 ovutils::eDest destR = (ovutils::eDest)indexR;
2118 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2119 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2120 if (!ov.queueBuffer(fd, offset, destR)) {
2121 ALOGE("%s: queueBuffer failed for display:%d",
2122 __FUNCTION__, mDpy);
2123 return false;
2124 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002125 }
2126 }
radhakrishnac9a67412013-09-25 17:40:42 +05302127 else{
2128 MdpPipeInfoSplit& pipe_info =
2129 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2130 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002131
radhakrishnac9a67412013-09-25 17:40:42 +05302132 ovutils::eDest indexL = pipe_info.lIndex;
2133 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002134
Sushil Chauhandefd3522014-05-13 18:17:12 -07002135 if (!mDpy && (i == mOverlapIndex)) {
2136 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2137 }
2138
radhakrishnac9a67412013-09-25 17:40:42 +05302139 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302140 int offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302141
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002142 if(ctx->mAD->draw(ctx, fd, offset)) {
2143 fd = ctx->mAD->getDstFd();
2144 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002145 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002146
radhakrishnac9a67412013-09-25 17:40:42 +05302147 if(rot) {
2148 rot->queueBuffer(fd, offset);
2149 fd = rot->getDstMemId();
2150 offset = rot->getDstOffset();
2151 }
2152
2153 //************* play left mixer **********
2154 if(indexL != ovutils::OV_INVALID) {
2155 ovutils::eDest destL = (ovutils::eDest)indexL;
2156 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2157 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2158 if (!ov.queueBuffer(fd, offset, destL)) {
2159 ALOGE("%s: queueBuffer failed for left mixer",
2160 __FUNCTION__);
2161 return false;
2162 }
2163 }
2164
2165 //************* play right mixer **********
2166 if(indexR != ovutils::OV_INVALID) {
2167 ovutils::eDest destR = (ovutils::eDest)indexR;
2168 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2169 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2170 if (!ov.queueBuffer(fd, offset, destR)) {
2171 ALOGE("%s: queueBuffer failed for right mixer",
2172 __FUNCTION__);
2173 return false;
2174 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002175 }
2176 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002177
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002178 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2179 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002180
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002181 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002182}
Saurabh Shahab47c692014-02-12 18:45:57 -08002183
2184//================MDPCompSrcSplit==============================================
2185bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002186 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002187 private_handle_t *hnd = (private_handle_t *)layer->handle;
2188 hwc_rect_t dst = layer->displayFrame;
2189 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2190 pipe_info.lIndex = ovutils::OV_INVALID;
2191 pipe_info.rIndex = ovutils::OV_INVALID;
2192
2193 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2194 //should have a higher priority than the right one. Pipe priorities are
2195 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002196
Saurabh Shahc62f3982014-03-05 14:28:26 -08002197 Overlay::PipeSpecs pipeSpecs;
2198 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2199 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2200 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2201 pipeSpecs.dpy = mDpy;
2202 pipeSpecs.fb = false;
2203
Saurabh Shahab47c692014-02-12 18:45:57 -08002204 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002205 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002206 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002207 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002208 }
2209
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002210 /* Use 2 pipes IF
2211 a) Layer's crop width is > 2048 or
2212 b) Layer's dest width > 2048 or
2213 c) On primary, driver has indicated with caps to split always. This is
2214 based on an empirically derived value of panel height. Applied only
2215 if the layer's width is > mixer's width
2216 */
2217
2218 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2219 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2220 int lSplit = getLeftSplit(ctx, mDpy);
2221 int dstWidth = dst.right - dst.left;
2222 int cropWidth = crop.right - crop.left;
2223
2224 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2225 cropWidth > qdutils::MAX_DISPLAY_DIM or
2226 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002227 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002228 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002229 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002230 }
2231
2232 // Return values
2233 // 1 Left pipe is higher priority, do nothing.
2234 // 0 Pipes of same priority.
2235 //-1 Right pipe is of higher priority, needs swap.
2236 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2237 pipe_info.rIndex) == -1) {
2238 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002239 }
2240 }
2241
2242 return true;
2243}
2244
Saurabh Shahab47c692014-02-12 18:45:57 -08002245int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2246 PipeLayerPair& PipeLayerPair) {
2247 private_handle_t *hnd = (private_handle_t *)layer->handle;
2248 if(!hnd) {
2249 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2250 return -1;
2251 }
2252 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2253 MdpPipeInfoSplit& mdp_info =
2254 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2255 Rotator **rot = &PipeLayerPair.rot;
2256 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2257 eIsFg isFg = IS_FG_OFF;
2258 eDest lDest = mdp_info.lIndex;
2259 eDest rDest = mdp_info.rIndex;
2260 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2261 hwc_rect_t dst = layer->displayFrame;
2262 int transform = layer->transform;
2263 eTransform orient = static_cast<eTransform>(transform);
2264 const int downscale = 0;
2265 int rotFlags = ROT_FLAGS_NONE;
2266 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2267 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2268
2269 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2270 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2271
2272 // Handle R/B swap
2273 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2274 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2275 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2276 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2277 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2278 }
2279
Saurabh Shah97e2d802014-04-14 18:03:54 -07002280 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002281 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002282
2283 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2284 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002285 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002286 }
2287
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002288 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002289 (*rot) = ctx->mRotMgr->getNext();
2290 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002291 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002292 //If the video is using a single pipe, enable BWC
2293 if(rDest == OV_INVALID) {
2294 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2295 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002296 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002297 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002298 ALOGE("%s: configRotator failed!", __FUNCTION__);
2299 return -1;
2300 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002301 whf.format = (*rot)->getDstFormat();
2302 updateSource(orient, whf, crop);
2303 rotFlags |= ROT_PREROTATED;
2304 }
2305
2306 //If 2 pipes being used, divide layer into half, crop and dst
2307 hwc_rect_t cropL = crop;
2308 hwc_rect_t cropR = crop;
2309 hwc_rect_t dstL = dst;
2310 hwc_rect_t dstR = dst;
2311 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2312 cropL.right = (crop.right + crop.left) / 2;
2313 cropR.left = cropL.right;
2314 sanitizeSourceCrop(cropL, cropR, hnd);
2315
2316 //Swap crops on H flip since 2 pipes are being used
2317 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2318 hwc_rect_t tmp = cropL;
2319 cropL = cropR;
2320 cropR = tmp;
2321 }
2322
2323 dstL.right = (dst.right + dst.left) / 2;
2324 dstR.left = dstL.right;
2325 }
2326
2327 //For the mdp, since either we are pre-rotating or MDP does flips
2328 orient = OVERLAY_TRANSFORM_0;
2329 transform = 0;
2330
2331 //configure left pipe
2332 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002333 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002334 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2335 (ovutils::eBlending) getBlending(layer->blending));
2336
2337 if(configMdp(ctx->mOverlay, pargL, orient,
2338 cropL, dstL, metadata, lDest) < 0) {
2339 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2340 return -1;
2341 }
2342 }
2343
2344 //configure right pipe
2345 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002346 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002347 static_cast<eRotFlags>(rotFlags),
2348 layer->planeAlpha,
2349 (ovutils::eBlending) getBlending(layer->blending));
2350 if(configMdp(ctx->mOverlay, pargR, orient,
2351 cropR, dstR, metadata, rDest) < 0) {
2352 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2353 return -1;
2354 }
2355 }
2356
2357 return 0;
2358}
2359
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002360}; //namespace
2361