blob: 010d533b75a968142863af2f6b7d9c1541258321 [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 Shah4fdde762013-04-30 18:47:33 -0700350 int crop_w = crop.right - crop.left;
351 int crop_h = crop.bottom - crop.top;
352 int dst_w = dst.right - dst.left;
353 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800354 float w_scale = ((float)crop_w / (float)dst_w);
355 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700356
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 /* Workaround for MDP HW limitation in DSI command mode panels where
358 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
359 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530360 * There also is a HW limilation in MDP, minimum block size is 2x2
361 * Fallback to GPU if height is less than 2.
362 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800363 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800364 return false;
365
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800366 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700367 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700368 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800369 const float w_dscale = w_scale;
370 const float h_dscale = h_scale;
371
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800372 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700373
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800374 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700375 /* On targets that doesnt support Decimation (eg.,8x26)
376 * maximum downscale support is overlay pipe downscale.
377 */
378 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
379 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800380 return false;
381 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700382 // Decimation on macrotile format layers is not supported.
383 if(isTileRendered(hnd)) {
384 /* MDP can read maximum MAX_DISPLAY_DIM width.
385 * Bail out if
386 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
387 * 2. exceeds maximum downscale limit
388 */
389 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
390 w_dscale > maxMDPDownscale ||
391 h_dscale > maxMDPDownscale) {
392 return false;
393 }
394 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800395 return false;
396 }
397 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700398 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 return false;
400 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700401 }
402
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
404 const uint32_t upscale =
405 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
406 const float w_uscale = 1.0f / w_scale;
407 const float h_uscale = 1.0f / h_scale;
408
409 if(w_uscale > upscale || h_uscale > upscale)
410 return false;
411 }
412
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800413 return true;
414}
415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700417 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800418
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800419 if(!isEnabled()) {
420 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700421 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530422 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530423 qdutils::MDPVersion::getInstance().is8x16() ||
424 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800425 ctx->mVideoTransFlag &&
426 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700427 //1 Padding round to shift pipes across mixers
428 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
429 __FUNCTION__);
430 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800431 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800432 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800433 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700434 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530436 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
437 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700438 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700439 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700440 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800441}
442
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800443void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
444 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
445 fbRect = getIntersection(fbRect, roi);
446}
447
448/* 1) Identify layers that are not visible or lying outside the updating ROI and
449 * drop them from composition.
450 * 2) If we have a scaling layer which needs cropping against generated
451 * ROI, reset ROI to full resolution. */
452bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
453 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700454 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800455 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800456
457 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800458 if(!isValidRect(visibleRect)) {
459 mCurrentFrame.drop[i] = true;
460 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800461 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800462 }
463
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800466 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700467
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468 if(!isValidRect(res)) {
469 mCurrentFrame.drop[i] = true;
470 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800471 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472 /* Reset frame ROI when any layer which needs scaling also needs ROI
473 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800474 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800475 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700476 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
477 mCurrentFrame.dropCount = 0;
478 return false;
479 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800480
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800481 /* deduct any opaque region from visibleRect */
482 if (layer->blending == HWC_BLENDING_NONE)
483 visibleRect = deductRect(visibleRect, res);
484 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700485 }
486 return true;
487}
488
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800489/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
490 * are updating. If DirtyRegion is applicable, calculate it by accounting all
491 * the changing layer's dirtyRegion. */
492void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
493 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700494 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800495 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700496 return;
497
498 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800499 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
500 (int)ctx->dpyAttr[mDpy].yres};
501
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700502 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800503 hwc_layer_1_t* layer = &list->hwLayers[index];
504 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800505 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700506 hwc_rect_t dst = layer->displayFrame;
507 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800508
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800509#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800510 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700511 {
512 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
513 int x_off = dst.left - src.left;
514 int y_off = dst.top - src.top;
515 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
516 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800517#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800518
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800519 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700520 }
521 }
522
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800523 /* No layer is updating. Still SF wants a refresh.*/
524 if(!isValidRect(roi))
525 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800526
527 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800529
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800530 ctx->listStats[mDpy].lRoi = roi;
531 if(!validateAndApplyROI(ctx, list))
532 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700533
534 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800535 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
536 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
537}
538
539void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
540 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
541 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
542
543 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
544 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
545 fbRect = getUnion(l_fbRect, r_fbRect);
546}
547/* 1) Identify layers that are not visible or lying outside BOTH the updating
548 * ROI's and drop them from composition. If a layer is spanning across both
549 * the halves of the screen but needed by only ROI, the non-contributing
550 * half will not be programmed for MDP.
551 * 2) If we have a scaling layer which needs cropping against generated
552 * ROI, reset ROI to full resolution. */
553bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
554 hwc_display_contents_1_t* list) {
555
556 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
557
558 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
559 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
560
561 for(int i = numAppLayers - 1; i >= 0; i--){
562 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
563 {
564 mCurrentFrame.drop[i] = true;
565 mCurrentFrame.dropCount++;
566 continue;
567 }
568
569 const hwc_layer_1_t* layer = &list->hwLayers[i];
570 hwc_rect_t dstRect = layer->displayFrame;
571
572 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
573 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
574 hwc_rect_t res = getUnion(l_res, r_res);
575
576 if(!isValidRect(l_res) && !isValidRect(r_res)) {
577 mCurrentFrame.drop[i] = true;
578 mCurrentFrame.dropCount++;
579 } else {
580 /* Reset frame ROI when any layer which needs scaling also needs ROI
581 * cropping */
582 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
583 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
584 mCurrentFrame.dropCount = 0;
585 return false;
586 }
587
588 if (layer->blending == HWC_BLENDING_NONE) {
589 visibleRectL = deductRect(visibleRectL, l_res);
590 visibleRectR = deductRect(visibleRectR, r_res);
591 }
592 }
593 }
594 return true;
595}
596/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
597 * are updating. If DirtyRegion is applicable, calculate it by accounting all
598 * the changing layer's dirtyRegion. */
599void MDPCompSplit::generateROI(hwc_context_t *ctx,
600 hwc_display_contents_1_t* list) {
601 if(!canPartialUpdate(ctx, list))
602 return;
603
604 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
605 int lSplit = getLeftSplit(ctx, mDpy);
606
607 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
608 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
609
610 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
611 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
612
613 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
614 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
615
616 for(int index = 0; index < numAppLayers; index++ ) {
617 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800618 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800619 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800620 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700621 hwc_rect_t dst = layer->displayFrame;
622 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800623
624#ifdef QCOM_BSP
625 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700626 {
627 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
628 int x_off = dst.left - src.left;
629 int y_off = dst.top - src.top;
630 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
631 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800632#endif
633
634 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
635 if(isValidRect(l_dst))
636 l_roi = getUnion(l_roi, l_dst);
637
638 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
639 if(isValidRect(r_dst))
640 r_roi = getUnion(r_roi, r_dst);
641 }
642 }
643
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700644 /* For panels that cannot accept commands in both the interfaces, we cannot
645 * send two ROI's (for each half). We merge them into single ROI and split
646 * them across lSplit for MDP mixer use. The ROI's will be merged again
647 * finally before udpating the panel in the driver. */
648 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
649 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
650 l_roi = getIntersection(temp_roi, l_frame);
651 r_roi = getIntersection(temp_roi, r_frame);
652 }
653
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800654 /* No layer is updating. Still SF wants a refresh. */
655 if(!isValidRect(l_roi) && !isValidRect(r_roi))
656 return;
657
658 l_roi = getSanitizeROI(l_roi, l_frame);
659 r_roi = getSanitizeROI(r_roi, r_frame);
660
661 ctx->listStats[mDpy].lRoi = l_roi;
662 ctx->listStats[mDpy].rRoi = r_roi;
663
664 if(!validateAndApplyROI(ctx, list))
665 resetROI(ctx, mDpy);
666
667 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
668 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
669 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
670 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
671 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
672 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700673}
674
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800675/* Checks for conditions where all the layers marked for MDP comp cannot be
676 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800677bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800678 hwc_display_contents_1_t* list){
679
Saurabh Shahaa236822013-04-24 18:07:26 -0700680 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800681 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800682
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700683 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700684 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
685 return false;
686 }
687
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800688 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700689 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
690 __FUNCTION__,
691 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800692 return false;
693 }
694
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800695 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
696 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
697 // Disable MDP comp on Secondary when the primary is highres panel and
698 // the secondary is a normal 1080p, because, MDP comp on secondary under
699 // in such usecase, decimation gets used for downscale and there will be
700 // a quality mismatch when there will be a fallback to GPU comp
701 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
702 __FUNCTION__);
703 return false;
704 }
705
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800706 // check for action safe flag and downscale mode which requires scaling.
707 if(ctx->dpyAttr[mDpy].mActionSafePresent
708 || ctx->dpyAttr[mDpy].mDownScaleMode) {
709 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
710 return false;
711 }
712
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800713 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800714 hwc_layer_1_t* layer = &list->hwLayers[i];
715 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800716
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800717 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700718 if(!canUseRotator(ctx, mDpy)) {
719 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
720 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700721 return false;
722 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800723 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530724
725 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
726 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700727 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530728 if(qdutils::MDPVersion::getInstance().is8x26() &&
729 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700730 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530731 (!isYuvBuffer(hnd)))
732 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800733 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700734
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700735 if(ctx->mAD->isDoable()) {
736 return false;
737 }
738
Saurabh Shahaa236822013-04-24 18:07:26 -0700739 //If all above hard conditions are met we can do full or partial MDP comp.
740 bool ret = false;
741 if(fullMDPComp(ctx, list)) {
742 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700743 } else if(fullMDPCompWithPTOR(ctx, list)) {
744 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700745 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 ret = true;
747 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530748
Saurabh Shahaa236822013-04-24 18:07:26 -0700749 return ret;
750}
751
752bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700753
754 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
755 return false;
756
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700757 //Will benefit presentation / secondary-only layer.
758 if((mDpy > HWC_DISPLAY_PRIMARY) &&
759 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
760 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
761 return false;
762 }
763
764 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
765 for(int i = 0; i < numAppLayers; i++) {
766 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700767 if(not mCurrentFrame.drop[i] and
768 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700769 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
770 return false;
771 }
772 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800773
Saurabh Shahaa236822013-04-24 18:07:26 -0700774 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700775 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
776 sizeof(mCurrentFrame.isFBComposed));
777 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
778 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700779
radhakrishnac9a67412013-09-25 17:40:42 +0530780 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800781 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530782 }
783
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800784 if(!postHeuristicsHandling(ctx, list)) {
785 ALOGD_IF(isDebug(), "post heuristic handling failed");
786 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700787 return false;
788 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700789 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
790 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700791 return true;
792}
793
Sushil Chauhandefd3522014-05-13 18:17:12 -0700794/* Full MDP Composition with Peripheral Tiny Overlap Removal.
795 * MDP bandwidth limitations can be avoided, if the overlap region
796 * covered by the smallest layer at a higher z-order, gets composed
797 * by Copybit on a render buffer, which can be queued to MDP.
798 */
799bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
800 hwc_display_contents_1_t* list) {
801
802 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
803 const int stagesForMDP = min(sMaxPipesPerMixer,
804 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
805
806 // Hard checks where we cannot use this mode
807 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
808 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
809 return false;
810 }
811
812 // Frame level checks
813 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
814 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
815 isSecurePresent(ctx, mDpy)) {
816 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
817 return false;
818 }
819
820 // Find overlap index
821 int overlapIdx = numAppLayers - 1;
822 uint32_t layerPixelCount, minPixelCount = 0;
823 for (int i = numAppLayers - 1; i >= 0; i--) {
824 hwc_layer_1_t* layer = &list->hwLayers[i];
825 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
826 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
827 if (!minPixelCount || (layerPixelCount < minPixelCount)) {
828 minPixelCount = layerPixelCount;
829 overlapIdx = i;
830 }
831 }
832
833 // No overlap
834 if (!overlapIdx)
835 return false;
836
837 /* We cannot use this composition mode, if:
838 1. A below layer needs scaling.
839 2. Overlap is not peripheral to display.
840 3. Overlap or a below layer has 90 degree transform.
841 4. Intersection of Overlap layer with a below layer is not valid.
842 5. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
843 */
844
845 hwc_rect_t overlap = list->hwLayers[overlapIdx].displayFrame;
846 if (!isPeripheral(overlap, ctx->mViewFrame[mDpy]))
847 return false;
848
849 if ((3 * (overlap.right - overlap.left) * (overlap.bottom - overlap.top)) >
850 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres))
851 return false;
852
853 for (int i = overlapIdx; i >= 0; i--) {
854 hwc_layer_1_t* layer = &list->hwLayers[i];
855 hwc_rect_t dispFrame = layer->displayFrame;
856
857 if (has90Transform(layer))
858 return false;
859
860 if (i < overlapIdx) {
861 if (needsScaling(layer) ||
862 !isValidRect(getIntersection(dispFrame, overlap)))
863 return false;
864 }
865 }
866
867 mOverlapIndex = overlapIdx;
868 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list, overlapIdx)) {
869 ALOGD_IF(isDebug(), "%s: Overlap prepare failed!",__FUNCTION__);
870 mOverlapIndex = -1;
871 return false;
872 }
873
874 hwc_rect_t sourceCrop[overlapIdx];
875 hwc_rect_t displayFrame[overlapIdx];
876
877 // Remove overlap from crop & displayFrame of below layers
878 for (int i = 0; i < overlapIdx; i++) {
879 hwc_layer_1_t* layer = &list->hwLayers[i];
880 displayFrame[i] = layer->displayFrame;
881 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
882
883 // Update layer attributes
884 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
885 hwc_rect_t destRect = deductRect(layer->displayFrame, overlap);
886 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
887 layer->transform);
888
889 layer->sourceCropf.left = (float)srcCrop.left;
890 layer->sourceCropf.top = (float)srcCrop.top;
891 layer->sourceCropf.right = (float)srcCrop.right;
892 layer->sourceCropf.bottom = (float)srcCrop.bottom;
893 }
894
895 mCurrentFrame.mdpCount = numAppLayers;
896 mCurrentFrame.fbCount = 0;
897 mCurrentFrame.fbZ = -1;
898
899 for (int j = 0; j < numAppLayers; j++)
900 mCurrentFrame.isFBComposed[j] = false;
901
902 bool result = postHeuristicsHandling(ctx, list);
903
904 // Restore layer attributes
905 for (int i = 0; i < overlapIdx; i++) {
906 hwc_layer_1_t* layer = &list->hwLayers[i];
907 layer->displayFrame = displayFrame[i];
908 layer->sourceCropf.left = (float)sourceCrop[i].left;
909 layer->sourceCropf.top = (float)sourceCrop[i].top;
910 layer->sourceCropf.right = (float)sourceCrop[i].right;
911 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
912 }
913
914 if (!result) {
915 mOverlapIndex = -1;
916 reset(ctx);
917 }
918
919 ALOGD_IF(isDebug(), "%s: Postheuristics %s!, Overlap index = %d",
920 __FUNCTION__, (result ? "successful" : "failed"), mOverlapIndex);
921 return result;
922}
923
Saurabh Shahaa236822013-04-24 18:07:26 -0700924bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
925{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700926 if(!sEnableMixedMode) {
927 //Mixed mode is disabled. No need to even try caching.
928 return false;
929 }
930
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700931 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800932 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800933 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800934 cacheBasedComp(ctx, list);
935 } else {
936 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800937 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700938 }
939
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700940 return ret;
941}
942
943bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
944 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700945 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
946 return false;
947
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700948 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700949 mCurrentFrame.reset(numAppLayers);
950 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700951
952 //If an MDP marked layer is unsupported cannot do partial MDP Comp
953 for(int i = 0; i < numAppLayers; i++) {
954 if(!mCurrentFrame.isFBComposed[i]) {
955 hwc_layer_1_t* layer = &list->hwLayers[i];
956 if(not isSupportedForMDPComp(ctx, layer)) {
957 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
958 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800959 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700960 return false;
961 }
962 }
963 }
964
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700965 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530966 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700967 if(!ret) {
968 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800969 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700970 return false;
971 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700972
973 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700974
radhakrishnac9a67412013-09-25 17:40:42 +0530975 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800976 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530977 }
978
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700979 //Will benefit cases where a video has non-updating background.
980 if((mDpy > HWC_DISPLAY_PRIMARY) and
981 (mdpCount > MAX_SEC_LAYERS)) {
982 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800983 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700984 return false;
985 }
986
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800987 if(!postHeuristicsHandling(ctx, list)) {
988 ALOGD_IF(isDebug(), "post heuristic handling failed");
989 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700990 return false;
991 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700992 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
993 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700994
Saurabh Shahaa236822013-04-24 18:07:26 -0700995 return true;
996}
997
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800998bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -0800999 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001000 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1001 return false;
1002
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001003 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001004 return false;
1005 }
1006
Saurabh Shahb772ae32013-11-18 15:40:02 -08001007 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001008 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1009 const int stagesForMDP = min(sMaxPipesPerMixer,
1010 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001011
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001012 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1013 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1014 int lastMDPSupportedIndex = numAppLayers;
1015 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001016
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001017 //Find the minimum MDP batch size
1018 for(int i = 0; i < numAppLayers;i++) {
1019 if(mCurrentFrame.drop[i]) {
1020 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001021 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001022 }
1023 hwc_layer_1_t* layer = &list->hwLayers[i];
1024 if(not isSupportedForMDPComp(ctx, layer)) {
1025 lastMDPSupportedIndex = i;
1026 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1027 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001028 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001029 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001030 }
1031
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001032 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1033 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1034 mCurrentFrame.dropCount);
1035
1036 //Start at a point where the fb batch should at least have 2 layers, for
1037 //this mode to be justified.
1038 while(fbBatchSize < 2) {
1039 ++fbBatchSize;
1040 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001041 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001042
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001043 //If there are no layers for MDP, this mode doesnt make sense.
1044 if(mdpBatchSize < 1) {
1045 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1046 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001047 return false;
1048 }
1049
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001050 mCurrentFrame.reset(numAppLayers);
1051
1052 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1053 while(mdpBatchSize > 0) {
1054 //Mark layers for MDP comp
1055 int mdpBatchLeft = mdpBatchSize;
1056 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1057 if(mCurrentFrame.drop[i]) {
1058 continue;
1059 }
1060 mCurrentFrame.isFBComposed[i] = false;
1061 --mdpBatchLeft;
1062 }
1063
1064 mCurrentFrame.fbZ = mdpBatchSize;
1065 mCurrentFrame.fbCount = fbBatchSize;
1066 mCurrentFrame.mdpCount = mdpBatchSize;
1067
1068 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1069 __FUNCTION__, mdpBatchSize, fbBatchSize,
1070 mCurrentFrame.dropCount);
1071
1072 if(postHeuristicsHandling(ctx, list)) {
1073 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001074 __FUNCTION__);
1075 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1076 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001077 return true;
1078 }
1079
1080 reset(ctx);
1081 --mdpBatchSize;
1082 ++fbBatchSize;
1083 }
1084
1085 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001086}
1087
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001088bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301089 if(mDpy or isSecurePresent(ctx, mDpy) or
1090 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001091 return false;
1092 }
1093 return true;
1094}
1095
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001096bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1097 hwc_display_contents_1_t* list){
1098 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1099 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1100 mDpy ) {
1101 return false;
1102 }
1103 return true;
1104}
1105
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001106bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1107 hwc_display_contents_1_t* list) {
1108 const bool secureOnly = true;
1109 return videoOnlyComp(ctx, list, not secureOnly) or
1110 videoOnlyComp(ctx, list, secureOnly);
1111}
1112
1113bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001114 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001115 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1116 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001117 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001118
Saurabh Shahaa236822013-04-24 18:07:26 -07001119 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001120 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001121 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001122 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001123
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001124 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1125 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001126 return false;
1127 }
1128
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001129 /* Bail out if we are processing only secured video layers
1130 * and we dont have any */
1131 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001132 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001133 return false;
1134 }
1135
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001136 if(mCurrentFrame.fbCount)
1137 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001138
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001139 if(sEnable4k2kYUVSplit){
1140 adjustForSourceSplit(ctx, list);
1141 }
1142
1143 if(!postHeuristicsHandling(ctx, list)) {
1144 ALOGD_IF(isDebug(), "post heuristic handling failed");
1145 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001146 return false;
1147 }
1148
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001149 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1150 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001151 return true;
1152}
1153
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001154/* Checks for conditions where YUV layers cannot be bypassed */
1155bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001156 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001157 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001158 return false;
1159 }
1160
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001161 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001162 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1163 return false;
1164 }
1165
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001166 if(isSecuring(ctx, layer)) {
1167 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1168 return false;
1169 }
1170
Saurabh Shah4fdde762013-04-30 18:47:33 -07001171 if(!isValidDimension(ctx, layer)) {
1172 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1173 __FUNCTION__);
1174 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001175 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001176
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001177 if(layer->planeAlpha < 0xFF) {
1178 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1179 in video only mode",
1180 __FUNCTION__);
1181 return false;
1182 }
1183
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001184 return true;
1185}
1186
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301187/* starts at fromIndex and check for each layer to find
1188 * if it it has overlapping with any Updating layer above it in zorder
1189 * till the end of the batch. returns true if it finds any intersection */
1190bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1191 int fromIndex, int toIndex) {
1192 for(int i = fromIndex; i < toIndex; i++) {
1193 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1194 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1195 return false;
1196 }
1197 }
1198 }
1199 return true;
1200}
1201
1202/* Checks if given layer at targetLayerIndex has any
1203 * intersection with all the updating layers in beween
1204 * fromIndex and toIndex. Returns true if it finds intersectiion */
1205bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1206 int fromIndex, int toIndex, int targetLayerIndex) {
1207 for(int i = fromIndex; i <= toIndex; i++) {
1208 if(!mCurrentFrame.isFBComposed[i]) {
1209 if(areLayersIntersecting(&list->hwLayers[i],
1210 &list->hwLayers[targetLayerIndex])) {
1211 return true;
1212 }
1213 }
1214 }
1215 return false;
1216}
1217
1218int MDPComp::getBatch(hwc_display_contents_1_t* list,
1219 int& maxBatchStart, int& maxBatchEnd,
1220 int& maxBatchCount) {
1221 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301222 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001223 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301224 while (i < mCurrentFrame.layerCount) {
1225 int batchCount = 0;
1226 int batchStart = i;
1227 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001228 /* Adjust batch Z order with the dropped layers so far */
1229 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301230 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301231 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301232 while(i < mCurrentFrame.layerCount) {
1233 if(!mCurrentFrame.isFBComposed[i]) {
1234 if(!batchCount) {
1235 i++;
1236 break;
1237 }
1238 updatingLayersAbove++;
1239 i++;
1240 continue;
1241 } else {
1242 if(mCurrentFrame.drop[i]) {
1243 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001244 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301245 continue;
1246 } else if(updatingLayersAbove <= 0) {
1247 batchCount++;
1248 batchEnd = i;
1249 i++;
1250 continue;
1251 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1252
1253 // We have a valid updating layer already. If layer-i not
1254 // have overlapping with all updating layers in between
1255 // batch-start and i, then we can add layer i to batch.
1256 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1257 batchCount++;
1258 batchEnd = i;
1259 i++;
1260 continue;
1261 } else if(canPushBatchToTop(list, batchStart, i)) {
1262 //If All the non-updating layers with in this batch
1263 //does not have intersection with the updating layers
1264 //above in z-order, then we can safely move the batch to
1265 //higher z-order. Increment fbZ as it is moving up.
1266 if( firstZReverseIndex < 0) {
1267 firstZReverseIndex = i;
1268 }
1269 batchCount++;
1270 batchEnd = i;
1271 fbZ += updatingLayersAbove;
1272 i++;
1273 updatingLayersAbove = 0;
1274 continue;
1275 } else {
1276 //both failed.start the loop again from here.
1277 if(firstZReverseIndex >= 0) {
1278 i = firstZReverseIndex;
1279 }
1280 break;
1281 }
1282 }
1283 }
1284 }
1285 if(batchCount > maxBatchCount) {
1286 maxBatchCount = batchCount;
1287 maxBatchStart = batchStart;
1288 maxBatchEnd = batchEnd;
1289 fbZOrder = fbZ;
1290 }
1291 }
1292 return fbZOrder;
1293}
1294
1295bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1296 hwc_display_contents_1_t* list) {
1297 /* Idea is to keep as many non-updating(cached) layers in FB and
1298 * send rest of them through MDP. This is done in 2 steps.
1299 * 1. Find the maximum contiguous batch of non-updating layers.
1300 * 2. See if we can improve this batch size for caching by adding
1301 * opaque layers around the batch, if they don't have
1302 * any overlapping with the updating layers in between.
1303 * NEVER mark an updating layer for caching.
1304 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001305
1306 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001307 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001308 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301309 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001310
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001311 /* Nothing is cached. No batching needed */
1312 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001313 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001314 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001315
1316 /* No MDP comp layers, try to use other comp modes */
1317 if(mCurrentFrame.mdpCount == 0) {
1318 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001319 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001320
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301321 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001322
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301323 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001324 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001325 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001326 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301327 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001328 if(!mCurrentFrame.drop[i]){
1329 //If an unsupported layer is being attempted to
1330 //be pulled out we should fail
1331 if(not isSupportedForMDPComp(ctx, layer)) {
1332 return false;
1333 }
1334 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001335 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001336 }
1337 }
1338
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301339 // update the frame data
1340 mCurrentFrame.fbZ = fbZ;
1341 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001342 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001343 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001344
1345 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301346 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001347
1348 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001349}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001350
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001351void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001352 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001353 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001354 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001355
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001356 for(int i = 0; i < numAppLayers; i++) {
1357 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001358 if(!mCurrentFrame.drop[i])
1359 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001360 mCurrentFrame.isFBComposed[i] = true;
1361 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001362 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001363 }
1364 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001365
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001366 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001367 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1368 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001369
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001370 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1371 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1372 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001373}
1374
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001375void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1376 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001377 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1378 for(int index = 0;index < nYuvCount; index++){
1379 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1380 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1381
1382 if(!isYUVDoable(ctx, layer)) {
1383 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1384 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1385 mCurrentFrame.fbCount++;
1386 }
1387 } else {
1388 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001389 private_handle_t *hnd = (private_handle_t *)layer->handle;
1390 if(!secureOnly || isSecureBuffer(hnd)) {
1391 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1392 mCurrentFrame.fbCount--;
1393 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001394 }
1395 }
1396 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001397
1398 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001399 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1400 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001401 mCurrentFrame.fbCount);
1402}
1403
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001404hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1405 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001406 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001407
1408 /* Update only the region of FB needed for composition */
1409 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1410 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1411 hwc_layer_1_t* layer = &list->hwLayers[i];
1412 hwc_rect_t dst = layer->displayFrame;
1413 fbRect = getUnion(fbRect, dst);
1414 }
1415 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001416 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001417 return fbRect;
1418}
1419
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001420bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1421 hwc_display_contents_1_t* list) {
1422
1423 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001424 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001425 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1426 return false;
1427 }
1428
1429 //Limitations checks
1430 if(!hwLimitationsCheck(ctx, list)) {
1431 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1432 return false;
1433 }
1434
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001435 //Configure framebuffer first if applicable
1436 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001437 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001438 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1439 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001440 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1441 __FUNCTION__);
1442 return false;
1443 }
1444 }
1445
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001446 mCurrentFrame.map();
1447
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001448 if(!allocLayerPipes(ctx, list)) {
1449 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001450 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001451 }
1452
1453 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001454 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001455 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001456 int mdpIndex = mCurrentFrame.layerToMDP[index];
1457 hwc_layer_1_t* layer = &list->hwLayers[index];
1458
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301459 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1460 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1461 mdpNextZOrder++;
1462 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001463 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1464 cur_pipe->zOrder = mdpNextZOrder++;
1465
radhakrishnac9a67412013-09-25 17:40:42 +05301466 private_handle_t *hnd = (private_handle_t *)layer->handle;
1467 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1468 if(configure4k2kYuv(ctx, layer,
1469 mCurrentFrame.mdpToLayer[mdpIndex])
1470 != 0 ){
1471 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1472 for layer %d",__FUNCTION__, index);
1473 return false;
1474 }
1475 else{
1476 mdpNextZOrder++;
1477 }
1478 continue;
1479 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001480 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1481 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301482 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001483 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001484 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001485 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001486 }
1487
Saurabh Shaha36be922013-12-16 18:18:39 -08001488 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1489 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1490 ,__FUNCTION__, mDpy);
1491 return false;
1492 }
1493
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001494 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001495 return true;
1496}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001497
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001498bool MDPComp::resourceCheck(hwc_context_t* ctx,
1499 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001500 const bool fbUsed = mCurrentFrame.fbCount;
1501 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1502 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1503 return false;
1504 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001505 // Init rotCount to number of rotate sessions used by other displays
1506 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1507 // Count the number of rotator sessions required for current display
1508 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1509 if(!mCurrentFrame.isFBComposed[index]) {
1510 hwc_layer_1_t* layer = &list->hwLayers[index];
1511 private_handle_t *hnd = (private_handle_t *)layer->handle;
1512 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1513 rotCount++;
1514 }
1515 }
1516 }
1517 // if number of layers to rotate exceeds max rotator sessions, bail out.
1518 if(rotCount > RotMgr::MAX_ROT_SESS) {
1519 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1520 __FUNCTION__, mDpy);
1521 return false;
1522 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001523 return true;
1524}
1525
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301526bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1527 hwc_display_contents_1_t* list) {
1528
1529 //A-family hw limitation:
1530 //If a layer need alpha scaling, MDP can not support.
1531 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1532 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1533 if(!mCurrentFrame.isFBComposed[i] &&
1534 isAlphaScaled( &list->hwLayers[i])) {
1535 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1536 return false;
1537 }
1538 }
1539 }
1540
1541 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1542 //If multiple layers requires downscaling and also they are overlapping
1543 //fall back to GPU since MDSS can not handle it.
1544 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1545 qdutils::MDPVersion::getInstance().is8x26()) {
1546 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1547 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1548 if(!mCurrentFrame.isFBComposed[i] &&
1549 isDownscaleRequired(botLayer)) {
1550 //if layer-i is marked for MDP and needs downscaling
1551 //check if any MDP layer on top of i & overlaps with layer-i
1552 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1553 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1554 if(!mCurrentFrame.isFBComposed[j] &&
1555 isDownscaleRequired(topLayer)) {
1556 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1557 topLayer->displayFrame);
1558 if(isValidRect(r))
1559 return false;
1560 }
1561 }
1562 }
1563 }
1564 }
1565 return true;
1566}
1567
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001568int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001569 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001570 char property[PROPERTY_VALUE_MAX];
1571
Raj Kamal4393eaa2014-06-06 13:45:20 +05301572 if(!ctx || !list) {
1573 ALOGE("%s: Invalid context or list",__FUNCTION__);
1574 mCachedFrame.reset();
1575 return -1;
1576 }
1577
1578 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1579
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001580 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1581 int currentFlags = atoi(property);
1582 if(currentFlags != sSimulationFlags) {
1583 sSimulationFlags = currentFlags;
1584 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1585 sSimulationFlags, sSimulationFlags);
1586 }
1587 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001588 mOverlapIndex = -1;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001589
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301590 //Do not cache the information for next draw cycle.
1591 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1592 ALOGI("%s: Unsupported layer count for mdp composition",
1593 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001594 mCachedFrame.reset();
1595 return -1;
1596 }
1597
Saurabh Shahb39f8152013-08-22 10:21:44 -07001598 //reset old data
1599 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001600 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1601 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301602
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001603 // Detect the start of animation and fall back to GPU only once to cache
1604 // all the layers in FB and display FB content untill animation completes.
1605 if(ctx->listStats[mDpy].isDisplayAnimating) {
1606 mCurrentFrame.needsRedraw = false;
1607 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1608 mCurrentFrame.needsRedraw = true;
1609 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1610 }
1611 setMDPCompLayerFlags(ctx, list);
1612 mCachedFrame.updateCounts(mCurrentFrame);
1613 ret = -1;
1614 return ret;
1615 } else {
1616 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1617 }
1618
Saurabh Shahb39f8152013-08-22 10:21:44 -07001619 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001620 if(isFrameDoable(ctx)) {
1621 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001622
Raj Kamal4393eaa2014-06-06 13:45:20 +05301623 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1624 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001625 setMDPCompLayerFlags(ctx, list);
1626 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001627 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001628 reset(ctx);
1629 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1630 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001631 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001632 }
1633 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001634 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1635 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001636 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001637 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001638
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001639 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001640 ALOGD("GEOMETRY change: %d",
1641 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001642 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001643 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001644 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001645 }
1646
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001647 mCachedFrame.cacheAll(list);
1648 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001649 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001650}
1651
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001652bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301653
1654 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301655 int mdpIndex = mCurrentFrame.layerToMDP[index];
1656 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1657 info.pipeInfo = new MdpYUVPipeInfo;
1658 info.rot = NULL;
1659 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301660
1661 pipe_info.lIndex = ovutils::OV_INVALID;
1662 pipe_info.rIndex = ovutils::OV_INVALID;
1663
Saurabh Shahc62f3982014-03-05 14:28:26 -08001664 Overlay::PipeSpecs pipeSpecs;
1665 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1666 pipeSpecs.needsScaling = true;
1667 pipeSpecs.dpy = mDpy;
1668 pipeSpecs.fb = false;
1669
1670 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301671 if(pipe_info.lIndex == ovutils::OV_INVALID){
1672 bRet = false;
1673 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1674 __FUNCTION__);
1675 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001676 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301677 if(pipe_info.rIndex == ovutils::OV_INVALID){
1678 bRet = false;
1679 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1680 __FUNCTION__);
1681 }
1682 return bRet;
1683}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001684
1685int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1686 int fd = -1;
1687 if (mOverlapIndex != -1) {
1688 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list, mOverlapIndex);
1689 if (fd < 0) {
1690 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
1691 mOverlapIndex = -1;
1692 }
1693 }
1694 return fd;
1695}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001696//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001697
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001698void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301699 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001700 //If 4k2k Yuv layer split is possible, and if
1701 //fbz is above 4k2k layer, increment fb zorder by 1
1702 //as we split 4k2k layer and increment zorder for right half
1703 //of the layer
1704 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301705 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1706 index++) {
1707 if(!mCurrentFrame.isFBComposed[index]) {
1708 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1709 mdpNextZOrder++;
1710 }
1711 mdpNextZOrder++;
1712 hwc_layer_1_t* layer = &list->hwLayers[index];
1713 private_handle_t *hnd = (private_handle_t *)layer->handle;
1714 if(is4kx2kYuvBuffer(hnd)) {
1715 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1716 mCurrentFrame.fbZ += 1;
1717 mdpNextZOrder++;
1718 //As we split 4kx2k yuv layer and program to 2 VG pipes
1719 //(if available) increase mdpcount by 1.
1720 mCurrentFrame.mdpCount++;
1721 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001722 }
1723 }
1724 }
radhakrishnac9a67412013-09-25 17:40:42 +05301725}
1726
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001727/*
1728 * Configures pipe(s) for MDP composition
1729 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001730int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001731 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001732 MdpPipeInfoNonSplit& mdp_info =
1733 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001734 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1735 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1736 eIsFg isFg = IS_FG_OFF;
1737 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001738
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001739 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1740 __FUNCTION__, layer, zOrder, dest);
1741
Saurabh Shah88e4d272013-09-03 13:31:29 -07001742 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001743 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001744}
1745
Saurabh Shah88e4d272013-09-03 13:31:29 -07001746bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001747 hwc_display_contents_1_t* list) {
1748 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001749
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001750 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001751
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001752 hwc_layer_1_t* layer = &list->hwLayers[index];
1753 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301754 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001755 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301756 continue;
1757 }
1758 }
1759
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001760 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001761 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001762 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001763 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001764 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001765
Saurabh Shahc62f3982014-03-05 14:28:26 -08001766 Overlay::PipeSpecs pipeSpecs;
1767 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1768 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1769 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1770 (qdutils::MDPVersion::getInstance().is8x26() and
1771 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1772 pipeSpecs.dpy = mDpy;
1773 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001774 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001775
Saurabh Shahc62f3982014-03-05 14:28:26 -08001776 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1777
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001778 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001779 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001780 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001781 }
1782 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001783 return true;
1784}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001785
radhakrishnac9a67412013-09-25 17:40:42 +05301786int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1787 PipeLayerPair& PipeLayerPair) {
1788 MdpYUVPipeInfo& mdp_info =
1789 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1790 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1791 eIsFg isFg = IS_FG_OFF;
1792 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1793 eDest lDest = mdp_info.lIndex;
1794 eDest rDest = mdp_info.rIndex;
1795
1796 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1797 lDest, rDest, &PipeLayerPair.rot);
1798}
1799
Saurabh Shah88e4d272013-09-03 13:31:29 -07001800bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001801
Raj Kamal4393eaa2014-06-06 13:45:20 +05301802 if(!isEnabled() or !mModeOn) {
1803 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301804 return true;
1805 }
1806
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001807 // Set the Handle timeout to true for MDP or MIXED composition.
1808 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1809 sHandleTimeout = true;
1810 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001811
1812 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001813 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001814
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001815 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1816 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001817 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001818 if(mCurrentFrame.isFBComposed[i]) continue;
1819
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001820 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001821 private_handle_t *hnd = (private_handle_t *)layer->handle;
1822 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001823 if (!(layer->flags & HWC_COLOR_FILL)) {
1824 ALOGE("%s handle null", __FUNCTION__);
1825 return false;
1826 }
1827 // No PLAY for Color layer
1828 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1829 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001830 }
1831
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001832 int mdpIndex = mCurrentFrame.layerToMDP[i];
1833
radhakrishnac9a67412013-09-25 17:40:42 +05301834 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1835 {
1836 MdpYUVPipeInfo& pipe_info =
1837 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1838 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1839 ovutils::eDest indexL = pipe_info.lIndex;
1840 ovutils::eDest indexR = pipe_info.rIndex;
1841 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301842 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301843 if(rot) {
1844 rot->queueBuffer(fd, offset);
1845 fd = rot->getDstMemId();
1846 offset = rot->getDstOffset();
1847 }
1848 if(indexL != ovutils::OV_INVALID) {
1849 ovutils::eDest destL = (ovutils::eDest)indexL;
1850 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1851 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1852 if (!ov.queueBuffer(fd, offset, destL)) {
1853 ALOGE("%s: queueBuffer failed for display:%d",
1854 __FUNCTION__, mDpy);
1855 return false;
1856 }
1857 }
1858
1859 if(indexR != ovutils::OV_INVALID) {
1860 ovutils::eDest destR = (ovutils::eDest)indexR;
1861 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1862 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1863 if (!ov.queueBuffer(fd, offset, destR)) {
1864 ALOGE("%s: queueBuffer failed for display:%d",
1865 __FUNCTION__, mDpy);
1866 return false;
1867 }
1868 }
1869 }
1870 else{
1871 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001872 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301873 ovutils::eDest dest = pipe_info.index;
1874 if(dest == ovutils::OV_INVALID) {
1875 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001876 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301877 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001878
radhakrishnac9a67412013-09-25 17:40:42 +05301879 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1880 continue;
1881 }
1882
Sushil Chauhandefd3522014-05-13 18:17:12 -07001883 if (!mDpy && (i == mOverlapIndex)) {
1884 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1885 }
1886
radhakrishnac9a67412013-09-25 17:40:42 +05301887 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1888 using pipe: %d", __FUNCTION__, layer,
1889 hnd, dest );
1890
1891 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301892 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301893
1894 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1895 if(rot) {
1896 if(!rot->queueBuffer(fd, offset))
1897 return false;
1898 fd = rot->getDstMemId();
1899 offset = rot->getDstOffset();
1900 }
1901
1902 if (!ov.queueBuffer(fd, offset, dest)) {
1903 ALOGE("%s: queueBuffer failed for display:%d ",
1904 __FUNCTION__, mDpy);
1905 return false;
1906 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001907 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001908
1909 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001910 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001911 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001912}
1913
Saurabh Shah88e4d272013-09-03 13:31:29 -07001914//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001915
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001916void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301917 hwc_display_contents_1_t* list){
1918 //if 4kx2k yuv layer is totally present in either in left half
1919 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301920 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301921 if(mCurrentFrame.fbZ >= 0) {
1922 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1923 index++) {
1924 if(!mCurrentFrame.isFBComposed[index]) {
1925 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1926 mdpNextZOrder++;
1927 }
1928 mdpNextZOrder++;
1929 hwc_layer_1_t* layer = &list->hwLayers[index];
1930 private_handle_t *hnd = (private_handle_t *)layer->handle;
1931 if(is4kx2kYuvBuffer(hnd)) {
1932 hwc_rect_t dst = layer->displayFrame;
1933 if((dst.left > lSplit) || (dst.right < lSplit)) {
1934 mCurrentFrame.mdpCount += 1;
1935 }
1936 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1937 mCurrentFrame.fbZ += 1;
1938 mdpNextZOrder++;
1939 }
1940 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001941 }
radhakrishnac9a67412013-09-25 17:40:42 +05301942 }
1943}
1944
Saurabh Shah88e4d272013-09-03 13:31:29 -07001945bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001946 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001947
Saurabh Shahc62f3982014-03-05 14:28:26 -08001948 const int lSplit = getLeftSplit(ctx, mDpy);
1949 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001950 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001951 pipe_info.lIndex = ovutils::OV_INVALID;
1952 pipe_info.rIndex = ovutils::OV_INVALID;
1953
Saurabh Shahc62f3982014-03-05 14:28:26 -08001954 Overlay::PipeSpecs pipeSpecs;
1955 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1956 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1957 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
1958 pipeSpecs.dpy = mDpy;
1959 pipeSpecs.mixer = Overlay::MIXER_LEFT;
1960 pipeSpecs.fb = false;
1961
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001962 // Acquire pipe only for the updating half
1963 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
1964 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
1965
1966 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001967 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001968 if(pipe_info.lIndex == ovutils::OV_INVALID)
1969 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001970 }
1971
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001972 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001973 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
1974 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001975 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001976 return false;
1977 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001978
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001979 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001980}
1981
Saurabh Shah88e4d272013-09-03 13:31:29 -07001982bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001983 hwc_display_contents_1_t* list) {
1984 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001985
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001986 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001987
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001988 hwc_layer_1_t* layer = &list->hwLayers[index];
1989 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301990 hwc_rect_t dst = layer->displayFrame;
1991 const int lSplit = getLeftSplit(ctx, mDpy);
1992 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1993 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001994 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301995 continue;
1996 }
1997 }
1998 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001999 int mdpIndex = mCurrentFrame.layerToMDP[index];
2000 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002001 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002002 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002003 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002004
Saurabh Shahc62f3982014-03-05 14:28:26 -08002005 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2006 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2007 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002008 return false;
2009 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002010 }
2011 return true;
2012}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002013
radhakrishnac9a67412013-09-25 17:40:42 +05302014int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2015 PipeLayerPair& PipeLayerPair) {
2016 const int lSplit = getLeftSplit(ctx, mDpy);
2017 hwc_rect_t dst = layer->displayFrame;
2018 if((dst.left > lSplit)||(dst.right < lSplit)){
2019 MdpYUVPipeInfo& mdp_info =
2020 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2021 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2022 eIsFg isFg = IS_FG_OFF;
2023 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2024 eDest lDest = mdp_info.lIndex;
2025 eDest rDest = mdp_info.rIndex;
2026
2027 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2028 lDest, rDest, &PipeLayerPair.rot);
2029 }
2030 else{
2031 return configure(ctx, layer, PipeLayerPair);
2032 }
2033}
2034
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002035/*
2036 * Configures pipe(s) for MDP composition
2037 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002038int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002039 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002040 MdpPipeInfoSplit& mdp_info =
2041 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002042 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2043 eIsFg isFg = IS_FG_OFF;
2044 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2045 eDest lDest = mdp_info.lIndex;
2046 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002047
2048 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2049 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2050
Saurabh Shah88e4d272013-09-03 13:31:29 -07002051 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002052 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002053}
2054
Saurabh Shah88e4d272013-09-03 13:31:29 -07002055bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002056
Raj Kamal4393eaa2014-06-06 13:45:20 +05302057 if(!isEnabled() or !mModeOn) {
2058 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302059 return true;
2060 }
2061
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002062 // Set the Handle timeout to true for MDP or MIXED composition.
2063 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2064 sHandleTimeout = true;
2065 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002066
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002067 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002068 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002069
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002070 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2071 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002072 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002073 if(mCurrentFrame.isFBComposed[i]) continue;
2074
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002075 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002076 private_handle_t *hnd = (private_handle_t *)layer->handle;
2077 if(!hnd) {
2078 ALOGE("%s handle null", __FUNCTION__);
2079 return false;
2080 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002081
2082 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2083 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002084 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002085
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002086 int mdpIndex = mCurrentFrame.layerToMDP[i];
2087
radhakrishnac9a67412013-09-25 17:40:42 +05302088 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2089 {
2090 MdpYUVPipeInfo& pipe_info =
2091 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2092 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2093 ovutils::eDest indexL = pipe_info.lIndex;
2094 ovutils::eDest indexR = pipe_info.rIndex;
2095 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302096 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302097 if(rot) {
2098 rot->queueBuffer(fd, offset);
2099 fd = rot->getDstMemId();
2100 offset = rot->getDstOffset();
2101 }
2102 if(indexL != ovutils::OV_INVALID) {
2103 ovutils::eDest destL = (ovutils::eDest)indexL;
2104 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2105 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2106 if (!ov.queueBuffer(fd, offset, destL)) {
2107 ALOGE("%s: queueBuffer failed for display:%d",
2108 __FUNCTION__, mDpy);
2109 return false;
2110 }
2111 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002112
radhakrishnac9a67412013-09-25 17:40:42 +05302113 if(indexR != ovutils::OV_INVALID) {
2114 ovutils::eDest destR = (ovutils::eDest)indexR;
2115 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2116 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2117 if (!ov.queueBuffer(fd, offset, destR)) {
2118 ALOGE("%s: queueBuffer failed for display:%d",
2119 __FUNCTION__, mDpy);
2120 return false;
2121 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002122 }
2123 }
radhakrishnac9a67412013-09-25 17:40:42 +05302124 else{
2125 MdpPipeInfoSplit& pipe_info =
2126 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2127 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002128
radhakrishnac9a67412013-09-25 17:40:42 +05302129 ovutils::eDest indexL = pipe_info.lIndex;
2130 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002131
Sushil Chauhandefd3522014-05-13 18:17:12 -07002132 if (!mDpy && (i == mOverlapIndex)) {
2133 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2134 }
2135
radhakrishnac9a67412013-09-25 17:40:42 +05302136 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302137 int offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302138
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002139 if(ctx->mAD->draw(ctx, fd, offset)) {
2140 fd = ctx->mAD->getDstFd();
2141 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002142 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002143
radhakrishnac9a67412013-09-25 17:40:42 +05302144 if(rot) {
2145 rot->queueBuffer(fd, offset);
2146 fd = rot->getDstMemId();
2147 offset = rot->getDstOffset();
2148 }
2149
2150 //************* play left mixer **********
2151 if(indexL != ovutils::OV_INVALID) {
2152 ovutils::eDest destL = (ovutils::eDest)indexL;
2153 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2154 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2155 if (!ov.queueBuffer(fd, offset, destL)) {
2156 ALOGE("%s: queueBuffer failed for left mixer",
2157 __FUNCTION__);
2158 return false;
2159 }
2160 }
2161
2162 //************* play right mixer **********
2163 if(indexR != ovutils::OV_INVALID) {
2164 ovutils::eDest destR = (ovutils::eDest)indexR;
2165 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2166 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2167 if (!ov.queueBuffer(fd, offset, destR)) {
2168 ALOGE("%s: queueBuffer failed for right mixer",
2169 __FUNCTION__);
2170 return false;
2171 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002172 }
2173 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002174
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002175 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2176 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002177
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002178 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002179}
Saurabh Shahab47c692014-02-12 18:45:57 -08002180
2181//================MDPCompSrcSplit==============================================
2182bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002183 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002184 private_handle_t *hnd = (private_handle_t *)layer->handle;
2185 hwc_rect_t dst = layer->displayFrame;
2186 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2187 pipe_info.lIndex = ovutils::OV_INVALID;
2188 pipe_info.rIndex = ovutils::OV_INVALID;
2189
2190 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2191 //should have a higher priority than the right one. Pipe priorities are
2192 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002193
Saurabh Shahc62f3982014-03-05 14:28:26 -08002194 Overlay::PipeSpecs pipeSpecs;
2195 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2196 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2197 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2198 pipeSpecs.dpy = mDpy;
2199 pipeSpecs.fb = false;
2200
Saurabh Shahab47c692014-02-12 18:45:57 -08002201 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002202 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002203 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002204 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002205 }
2206
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002207 /* Use 2 pipes IF
2208 a) Layer's crop width is > 2048 or
2209 b) Layer's dest width > 2048 or
2210 c) On primary, driver has indicated with caps to split always. This is
2211 based on an empirically derived value of panel height. Applied only
2212 if the layer's width is > mixer's width
2213 */
2214
2215 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2216 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2217 int lSplit = getLeftSplit(ctx, mDpy);
2218 int dstWidth = dst.right - dst.left;
2219 int cropWidth = crop.right - crop.left;
2220
2221 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2222 cropWidth > qdutils::MAX_DISPLAY_DIM or
2223 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002224 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002225 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002226 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002227 }
2228
2229 // Return values
2230 // 1 Left pipe is higher priority, do nothing.
2231 // 0 Pipes of same priority.
2232 //-1 Right pipe is of higher priority, needs swap.
2233 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2234 pipe_info.rIndex) == -1) {
2235 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002236 }
2237 }
2238
2239 return true;
2240}
2241
Saurabh Shahab47c692014-02-12 18:45:57 -08002242int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2243 PipeLayerPair& PipeLayerPair) {
2244 private_handle_t *hnd = (private_handle_t *)layer->handle;
2245 if(!hnd) {
2246 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2247 return -1;
2248 }
2249 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2250 MdpPipeInfoSplit& mdp_info =
2251 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2252 Rotator **rot = &PipeLayerPair.rot;
2253 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2254 eIsFg isFg = IS_FG_OFF;
2255 eDest lDest = mdp_info.lIndex;
2256 eDest rDest = mdp_info.rIndex;
2257 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2258 hwc_rect_t dst = layer->displayFrame;
2259 int transform = layer->transform;
2260 eTransform orient = static_cast<eTransform>(transform);
2261 const int downscale = 0;
2262 int rotFlags = ROT_FLAGS_NONE;
2263 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2264 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2265
2266 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2267 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2268
2269 // Handle R/B swap
2270 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2271 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2272 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2273 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2274 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2275 }
2276
Saurabh Shah97e2d802014-04-14 18:03:54 -07002277 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002278 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002279
2280 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2281 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002282 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002283 }
2284
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002285 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002286 (*rot) = ctx->mRotMgr->getNext();
2287 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002288 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002289 //If the video is using a single pipe, enable BWC
2290 if(rDest == OV_INVALID) {
2291 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2292 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002293 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002294 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002295 ALOGE("%s: configRotator failed!", __FUNCTION__);
2296 return -1;
2297 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002298 whf.format = (*rot)->getDstFormat();
2299 updateSource(orient, whf, crop);
2300 rotFlags |= ROT_PREROTATED;
2301 }
2302
2303 //If 2 pipes being used, divide layer into half, crop and dst
2304 hwc_rect_t cropL = crop;
2305 hwc_rect_t cropR = crop;
2306 hwc_rect_t dstL = dst;
2307 hwc_rect_t dstR = dst;
2308 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2309 cropL.right = (crop.right + crop.left) / 2;
2310 cropR.left = cropL.right;
2311 sanitizeSourceCrop(cropL, cropR, hnd);
2312
2313 //Swap crops on H flip since 2 pipes are being used
2314 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2315 hwc_rect_t tmp = cropL;
2316 cropL = cropR;
2317 cropR = tmp;
2318 }
2319
2320 dstL.right = (dst.right + dst.left) / 2;
2321 dstR.left = dstL.right;
2322 }
2323
2324 //For the mdp, since either we are pre-rotating or MDP does flips
2325 orient = OVERLAY_TRANSFORM_0;
2326 transform = 0;
2327
2328 //configure left pipe
2329 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002330 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002331 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2332 (ovutils::eBlending) getBlending(layer->blending));
2333
2334 if(configMdp(ctx->mOverlay, pargL, orient,
2335 cropL, dstL, metadata, lDest) < 0) {
2336 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2337 return -1;
2338 }
2339 }
2340
2341 //configure right pipe
2342 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002343 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002344 static_cast<eRotFlags>(rotFlags),
2345 layer->planeAlpha,
2346 (ovutils::eBlending) getBlending(layer->blending));
2347 if(configMdp(ctx->mOverlay, pargR, orient,
2348 cropR, dstR, metadata, rDest) < 0) {
2349 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2350 return -1;
2351 }
2352 }
2353
2354 return 0;
2355}
2356
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002357}; //namespace
2358