blob: 6084d8d08c43741da652275fd9d3272d8e1634e0 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
132 int val = atoi(property);
133 if(val >= 0)
134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 }
136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
138 // Idle invalidation is not necessary on command mode panels
139 long idle_timeout = DEFAULT_IDLE_TIME;
140 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
141 if(atoi(property) != 0)
142 idle_timeout = atoi(property);
143 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800144
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400145 //create Idle Invalidator only when not disabled through property
146 if(idle_timeout != -1)
147 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800148
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400149 if(idleInvalidator == NULL) {
150 ALOGE("%s: failed to instantiate idleInvalidator object",
151 __FUNCTION__);
152 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530153 idleInvalidator->init(timeout_handler, ctx,
154 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400155 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800156 }
radhakrishnac9a67412013-09-25 17:40:42 +0530157
Saurabh Shah7c727642014-06-02 15:47:14 -0700158 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700159 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700160 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
161 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
162 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530163 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530164 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700165
166 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
167 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
168 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
169 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
170 HWC_DISPLAY_PRIMARY);
171 }
172
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700173 return true;
174}
175
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800176void MDPComp::reset(hwc_context_t *ctx) {
177 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700178 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800179 ctx->mOverlay->clear(mDpy);
180 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700181}
182
Raj Kamal4393eaa2014-06-06 13:45:20 +0530183void MDPComp::reset() {
184 sHandleTimeout = false;
185 mModeOn = false;
186}
187
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700188void MDPComp::timeout_handler(void *udata) {
189 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
190
191 if(!ctx) {
192 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
193 return;
194 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800195 Locker::Autolock _l(ctx->mDrawLock);
196 // Handle timeout event only if the previous composition is MDP or MIXED.
197 if(!sHandleTimeout) {
198 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
199 return;
200 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700201 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700202 ALOGE("%s: HWC proc not registered", __FUNCTION__);
203 return;
204 }
205 sIdleFallBack = true;
206 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700207 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700208}
209
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800210void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800211 hwc_display_contents_1_t* list) {
212 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800213
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800214 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800215 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800216 if(!mCurrentFrame.isFBComposed[index]) {
217 layerProp[index].mFlags |= HWC_MDPCOMP;
218 layer->compositionType = HWC_OVERLAY;
219 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700221 /* Drop the layer when its already present in FB OR when it lies
222 * outside frame's ROI */
223 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800224 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700225 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800226 }
227 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500229
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800230void MDPComp::setRedraw(hwc_context_t *ctx,
231 hwc_display_contents_1_t* list) {
232 mCurrentFrame.needsRedraw = false;
233 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
234 (list->flags & HWC_GEOMETRY_CHANGED) ||
235 isSkipPresent(ctx, mDpy)) {
236 mCurrentFrame.needsRedraw = true;
237 }
238}
239
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800240MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700241 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800242}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800243
Saurabh Shahaa236822013-04-24 18:07:26 -0700244void MDPComp::FrameInfo::reset(const int& numLayers) {
245 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246 if(mdpToLayer[i].pipeInfo) {
247 delete mdpToLayer[i].pipeInfo;
248 mdpToLayer[i].pipeInfo = NULL;
249 //We dont own the rotator
250 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800251 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800252 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800253
254 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
255 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700256 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
Saurabh Shahaa236822013-04-24 18:07:26 -0700258 layerCount = numLayers;
259 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700261 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800262 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263}
264
Saurabh Shahaa236822013-04-24 18:07:26 -0700265void MDPComp::FrameInfo::map() {
266 // populate layer and MDP maps
267 int mdpIdx = 0;
268 for(int idx = 0; idx < layerCount; idx++) {
269 if(!isFBComposed[idx]) {
270 mdpToLayer[mdpIdx].listIndex = idx;
271 layerToMDP[idx] = mdpIdx++;
272 }
273 }
274}
275
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800276MDPComp::LayerCache::LayerCache() {
277 reset();
278}
279
280void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700281 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530282 memset(&isFBComposed, true, sizeof(isFBComposed));
283 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800284 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700285}
286
287void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530288 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289 for(int i = 0; i < numAppLayers; i++) {
290 hnd[i] = list->hwLayers[i].handle;
291 }
292}
293
294void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530296 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
297 memcpy(&drop, &curFrame.drop, sizeof(drop));
298}
299
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800300bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
301 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530302 if(layerCount != curFrame.layerCount)
303 return false;
304 for(int i = 0; i < curFrame.layerCount; i++) {
305 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
306 (curFrame.drop[i] != drop[i])) {
307 return false;
308 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800309 if(curFrame.isFBComposed[i] &&
310 (hnd[i] != list->hwLayers[i].handle)){
311 return false;
312 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530313 }
314 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800315}
316
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700317bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
318 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800319 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700320 (not isValidDimension(ctx,layer))
321 //More conditions here, SKIP, sRGB+Blend etc
322 ) {
323 return false;
324 }
325 return true;
326}
327
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530328bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800329 private_handle_t *hnd = (private_handle_t *)layer->handle;
330
331 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700332 if (layer->flags & HWC_COLOR_FILL) {
333 // Color layer
334 return true;
335 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800336 ALOGE("%s: layer handle is NULL", __FUNCTION__);
337 return false;
338 }
339
Naseer Ahmede850a802013-09-06 13:12:52 -0400340 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400341 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400342 return false;
343
Saurabh Shah62e1d732013-09-17 10:44:05 -0700344 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700345 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700346 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700347 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
348 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 int dst_w = dst.right - dst.left;
350 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800351 float w_scale = ((float)crop_w / (float)dst_w);
352 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530353 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700354
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800355 /* Workaround for MDP HW limitation in DSI command mode panels where
356 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
357 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530358 * There also is a HW limilation in MDP, minimum block size is 2x2
359 * Fallback to GPU if height is less than 2.
360 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800361 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800362 return false;
363
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800364 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530365 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800366 const float w_dscale = w_scale;
367 const float h_dscale = h_scale;
368
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800369 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700370
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530371 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700372 /* On targets that doesnt support Decimation (eg.,8x26)
373 * maximum downscale support is overlay pipe downscale.
374 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530375 if(crop_w > mdpHw.getMaxMixerWidth() ||
376 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700377 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800378 return false;
379 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700380 // Decimation on macrotile format layers is not supported.
381 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530382 /* Bail out if
383 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700384 * 2. exceeds maximum downscale limit
385 */
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530386 if(((crop_w > mdpHw.getMaxMixerWidth()) &&
387 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700388 w_dscale > maxMDPDownscale ||
389 h_dscale > maxMDPDownscale) {
390 return false;
391 }
392 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800393 return false;
394 }
395 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700396 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 return false;
398 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 }
400
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800401 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530402 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800403 const float w_uscale = 1.0f / w_scale;
404 const float h_uscale = 1.0f / h_scale;
405
406 if(w_uscale > upscale || h_uscale > upscale)
407 return false;
408 }
409
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return true;
411}
412
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800413bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700414 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800416 if(!isEnabled()) {
417 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530419 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530420 qdutils::MDPVersion::getInstance().is8x16() ||
421 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800422 ctx->mVideoTransFlag &&
423 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700424 //1 Padding round to shift pipes across mixers
425 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
426 __FUNCTION__);
427 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800428 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800429 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800430 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700431 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700432 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530433 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
434 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700436 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700437 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800438}
439
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800440void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
441 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
442 fbRect = getIntersection(fbRect, roi);
443}
444
445/* 1) Identify layers that are not visible or lying outside the updating ROI and
446 * drop them from composition.
447 * 2) If we have a scaling layer which needs cropping against generated
448 * ROI, reset ROI to full resolution. */
449bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
450 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700451 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800452 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800453
454 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800455 if(!isValidRect(visibleRect)) {
456 mCurrentFrame.drop[i] = true;
457 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800458 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800459 }
460
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700461 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700462 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800463 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 if(!isValidRect(res)) {
466 mCurrentFrame.drop[i] = true;
467 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800468 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 /* Reset frame ROI when any layer which needs scaling also needs ROI
470 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800471 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800472 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700473 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
474 mCurrentFrame.dropCount = 0;
475 return false;
476 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800477
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800478 /* deduct any opaque region from visibleRect */
479 if (layer->blending == HWC_BLENDING_NONE)
480 visibleRect = deductRect(visibleRect, res);
481 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700482 }
483 return true;
484}
485
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800486/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
487 * are updating. If DirtyRegion is applicable, calculate it by accounting all
488 * the changing layer's dirtyRegion. */
489void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
490 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700491 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800492 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700493 return;
494
495 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
497 (int)ctx->dpyAttr[mDpy].yres};
498
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700499 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800500 hwc_layer_1_t* layer = &list->hwLayers[index];
501 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800502 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700503 hwc_rect_t dst = layer->displayFrame;
504 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800505
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800506#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800507 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700508 {
509 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
510 int x_off = dst.left - src.left;
511 int y_off = dst.top - src.top;
512 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
513 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800514#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800515
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800516 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700517 }
518 }
519
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800520 /* No layer is updating. Still SF wants a refresh.*/
521 if(!isValidRect(roi))
522 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800523
524 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800525 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800526
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527 ctx->listStats[mDpy].lRoi = roi;
528 if(!validateAndApplyROI(ctx, list))
529 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700530
531 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800532 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
533 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
534}
535
536void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
537 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
538 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
539
540 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
541 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
542 fbRect = getUnion(l_fbRect, r_fbRect);
543}
544/* 1) Identify layers that are not visible or lying outside BOTH the updating
545 * ROI's and drop them from composition. If a layer is spanning across both
546 * the halves of the screen but needed by only ROI, the non-contributing
547 * half will not be programmed for MDP.
548 * 2) If we have a scaling layer which needs cropping against generated
549 * ROI, reset ROI to full resolution. */
550bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
551 hwc_display_contents_1_t* list) {
552
553 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
554
555 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
556 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
557
558 for(int i = numAppLayers - 1; i >= 0; i--){
559 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
560 {
561 mCurrentFrame.drop[i] = true;
562 mCurrentFrame.dropCount++;
563 continue;
564 }
565
566 const hwc_layer_1_t* layer = &list->hwLayers[i];
567 hwc_rect_t dstRect = layer->displayFrame;
568
569 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
570 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
571 hwc_rect_t res = getUnion(l_res, r_res);
572
573 if(!isValidRect(l_res) && !isValidRect(r_res)) {
574 mCurrentFrame.drop[i] = true;
575 mCurrentFrame.dropCount++;
576 } else {
577 /* Reset frame ROI when any layer which needs scaling also needs ROI
578 * cropping */
579 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
580 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
581 mCurrentFrame.dropCount = 0;
582 return false;
583 }
584
585 if (layer->blending == HWC_BLENDING_NONE) {
586 visibleRectL = deductRect(visibleRectL, l_res);
587 visibleRectR = deductRect(visibleRectR, r_res);
588 }
589 }
590 }
591 return true;
592}
593/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
594 * are updating. If DirtyRegion is applicable, calculate it by accounting all
595 * the changing layer's dirtyRegion. */
596void MDPCompSplit::generateROI(hwc_context_t *ctx,
597 hwc_display_contents_1_t* list) {
598 if(!canPartialUpdate(ctx, list))
599 return;
600
601 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
602 int lSplit = getLeftSplit(ctx, mDpy);
603
604 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
605 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
606
607 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
608 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
609
610 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
611 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
612
613 for(int index = 0; index < numAppLayers; index++ ) {
614 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800615 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800616 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800617 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700618 hwc_rect_t dst = layer->displayFrame;
619 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800620
621#ifdef QCOM_BSP
622 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700623 {
624 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
625 int x_off = dst.left - src.left;
626 int y_off = dst.top - src.top;
627 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
628 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800629#endif
630
631 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
632 if(isValidRect(l_dst))
633 l_roi = getUnion(l_roi, l_dst);
634
635 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
636 if(isValidRect(r_dst))
637 r_roi = getUnion(r_roi, r_dst);
638 }
639 }
640
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700641 /* For panels that cannot accept commands in both the interfaces, we cannot
642 * send two ROI's (for each half). We merge them into single ROI and split
643 * them across lSplit for MDP mixer use. The ROI's will be merged again
644 * finally before udpating the panel in the driver. */
645 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
646 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
647 l_roi = getIntersection(temp_roi, l_frame);
648 r_roi = getIntersection(temp_roi, r_frame);
649 }
650
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800651 /* No layer is updating. Still SF wants a refresh. */
652 if(!isValidRect(l_roi) && !isValidRect(r_roi))
653 return;
654
655 l_roi = getSanitizeROI(l_roi, l_frame);
656 r_roi = getSanitizeROI(r_roi, r_frame);
657
658 ctx->listStats[mDpy].lRoi = l_roi;
659 ctx->listStats[mDpy].rRoi = r_roi;
660
661 if(!validateAndApplyROI(ctx, list))
662 resetROI(ctx, mDpy);
663
664 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
665 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
666 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
667 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
668 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
669 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700670}
671
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800672/* Checks for conditions where all the layers marked for MDP comp cannot be
673 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800674bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800675 hwc_display_contents_1_t* list){
676
Saurabh Shahaa236822013-04-24 18:07:26 -0700677 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800678 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800679
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700680 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700681 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
682 return false;
683 }
684
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800685 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700686 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
687 __FUNCTION__,
688 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800689 return false;
690 }
691
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530692 MDPVersion& mdpHw = MDPVersion::getInstance();
693 if(mDpy > HWC_DISPLAY_PRIMARY &&
694 (priDispW > mdpHw.getMaxMixerWidth()) &&
695 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800696 // Disable MDP comp on Secondary when the primary is highres panel and
697 // the secondary is a normal 1080p, because, MDP comp on secondary under
698 // in such usecase, decimation gets used for downscale and there will be
699 // a quality mismatch when there will be a fallback to GPU comp
700 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
701 __FUNCTION__);
702 return false;
703 }
704
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800705 // check for action safe flag and downscale mode which requires scaling.
706 if(ctx->dpyAttr[mDpy].mActionSafePresent
707 || ctx->dpyAttr[mDpy].mDownScaleMode) {
708 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
709 return false;
710 }
711
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800712 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800713 hwc_layer_1_t* layer = &list->hwLayers[i];
714 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800715
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800716 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700717 if(!canUseRotator(ctx, mDpy)) {
718 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
719 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700720 return false;
721 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800722 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530723
724 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
725 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700726 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530727 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
728 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
729 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800730 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700731
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700732 if(ctx->mAD->isDoable()) {
733 return false;
734 }
735
Saurabh Shahaa236822013-04-24 18:07:26 -0700736 //If all above hard conditions are met we can do full or partial MDP comp.
737 bool ret = false;
738 if(fullMDPComp(ctx, list)) {
739 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700740 } else if(fullMDPCompWithPTOR(ctx, list)) {
741 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700742 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700743 ret = true;
744 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530745
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 return ret;
747}
748
749bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700750
751 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
752 return false;
753
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700754 //Will benefit presentation / secondary-only layer.
755 if((mDpy > HWC_DISPLAY_PRIMARY) &&
756 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
757 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
758 return false;
759 }
760
761 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
762 for(int i = 0; i < numAppLayers; i++) {
763 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700764 if(not mCurrentFrame.drop[i] and
765 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700766 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
767 return false;
768 }
769 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800770
Saurabh Shahaa236822013-04-24 18:07:26 -0700771 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700772 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
773 sizeof(mCurrentFrame.isFBComposed));
774 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
775 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700776
Raj Kamal389d6e32014-08-04 14:43:24 +0530777 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800778 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530779 }
780
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800781 if(!postHeuristicsHandling(ctx, list)) {
782 ALOGD_IF(isDebug(), "post heuristic handling failed");
783 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700784 return false;
785 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700786 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
787 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700788 return true;
789}
790
Sushil Chauhandefd3522014-05-13 18:17:12 -0700791/* Full MDP Composition with Peripheral Tiny Overlap Removal.
792 * MDP bandwidth limitations can be avoided, if the overlap region
793 * covered by the smallest layer at a higher z-order, gets composed
794 * by Copybit on a render buffer, which can be queued to MDP.
795 */
796bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
797 hwc_display_contents_1_t* list) {
798
799 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
800 const int stagesForMDP = min(sMaxPipesPerMixer,
801 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
802
803 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700804 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700805 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
806 return false;
807 }
808
809 // Frame level checks
810 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
811 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
812 isSecurePresent(ctx, mDpy)) {
813 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
814 return false;
815 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700816 // MDP comp checks
817 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700818 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700819 if(not isSupportedForMDPComp(ctx, layer)) {
820 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
821 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700822 }
823 }
824
Sushil Chauhandefd3522014-05-13 18:17:12 -0700825 /* We cannot use this composition mode, if:
826 1. A below layer needs scaling.
827 2. Overlap is not peripheral to display.
828 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700829 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700830 */
831
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700832 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
833 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
834 memset(overlapRect, 0, sizeof(overlapRect));
835 int layerPixelCount, minPixelCount = 0;
836 int numPTORLayersFound = 0;
837 for (int i = numAppLayers-1; (i >= 0 &&
838 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700839 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700840 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700841 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700842 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
843 // PTOR layer should be peripheral and cannot have transform
844 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
845 has90Transform(layer)) {
846 continue;
847 }
848 if((3 * (layerPixelCount + minPixelCount)) >
849 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
850 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
851 continue;
852 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700853 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700854 for (int j = i-1; j >= 0; j--) {
855 // Check if the layers below this layer qualifies for PTOR comp
856 hwc_layer_1_t* layer = &list->hwLayers[j];
857 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700858 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700859 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700860 if (isValidRect(getIntersection(dispFrame, disFrame))) {
861 if (has90Transform(layer) || needsScaling(layer)) {
862 found = false;
863 break;
864 }
865 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700866 }
867 }
868 // Store the minLayer Index
869 if(found) {
870 minLayerIndex[numPTORLayersFound] = i;
871 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
872 minPixelCount += layerPixelCount;
873 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700874 }
875 }
876
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700877 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
878 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
879 __FUNCTION__);
880 // reset second minLayerIndex[1];
881 minLayerIndex[1] = -1;
882 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700883 }
884
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700885 // No overlap layers
886 if (!numPTORLayersFound)
887 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700888
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700889 ctx->mPtorInfo.count = numPTORLayersFound;
890 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
891 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
892 }
893
894 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
895 // reset PTOR
896 ctx->mPtorInfo.count = 0;
897 return false;
898 }
899 // Store the displayFrame and the sourceCrops of the layers
900 hwc_rect_t displayFrame[numAppLayers];
901 hwc_rect_t sourceCrop[numAppLayers];
902 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 hwc_layer_1_t* layer = &list->hwLayers[i];
904 displayFrame[i] = layer->displayFrame;
905 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700907
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700908 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
909 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
910
Xu Yangcda012c2014-07-30 21:57:21 +0800911 // Store the blending mode, planeAlpha, and transform of PTOR layers
912 int32_t blending[numPTORLayersFound];
913 uint8_t planeAlpha[numPTORLayersFound];
914 uint32_t transform[numPTORLayersFound];
915
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700916 for(int j = 0; j < numPTORLayersFound; j++) {
917 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700918
919 // Update src crop of PTOR layer
920 hwc_layer_1_t* layer = &list->hwLayers[index];
921 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
922 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
923 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
924 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
925
926 // Store & update w, h, format of PTOR layer
927 private_handle_t *hnd = (private_handle_t *)layer->handle;
928 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
929 layerWhf[j] = whf;
930 hnd->width = renderBuf->width;
931 hnd->height = renderBuf->height;
932 hnd->format = renderBuf->format;
933
Xu Yangcda012c2014-07-30 21:57:21 +0800934 // Store & update blending mode, planeAlpha and transform of PTOR layer
935 blending[j] = layer->blending;
936 planeAlpha[j] = layer->planeAlpha;
937 transform[j] = layer->transform;
938 layer->blending = HWC_BLENDING_NONE;
939 layer->planeAlpha = 0xFF;
940 layer->transform = 0;
941
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700942 // Remove overlap from crop & displayFrame of below layers
943 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700944 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700945 if(!isValidRect(getIntersection(layer->displayFrame,
946 overlapRect[j]))) {
947 continue;
948 }
949 // Update layer attributes
950 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
951 hwc_rect_t destRect = deductRect(layer->displayFrame,
952 overlapRect[j]);
953 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
954 layer->transform);
955 layer->sourceCropf.left = (float)srcCrop.left;
956 layer->sourceCropf.top = (float)srcCrop.top;
957 layer->sourceCropf.right = (float)srcCrop.right;
958 layer->sourceCropf.bottom = (float)srcCrop.bottom;
959 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700960 }
961
962 mCurrentFrame.mdpCount = numAppLayers;
963 mCurrentFrame.fbCount = 0;
964 mCurrentFrame.fbZ = -1;
965
966 for (int j = 0; j < numAppLayers; j++)
967 mCurrentFrame.isFBComposed[j] = false;
968
969 bool result = postHeuristicsHandling(ctx, list);
970
971 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700972 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700973 hwc_layer_1_t* layer = &list->hwLayers[i];
974 layer->displayFrame = displayFrame[i];
975 layer->sourceCropf.left = (float)sourceCrop[i].left;
976 layer->sourceCropf.top = (float)sourceCrop[i].top;
977 layer->sourceCropf.right = (float)sourceCrop[i].right;
978 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
979 }
980
Xu Yangcda012c2014-07-30 21:57:21 +0800981 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700982 for (int i = 0; i < numPTORLayersFound; i++) {
983 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +0800984 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700985 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
986 hnd->width = layerWhf[i].w;
987 hnd->height = layerWhf[i].h;
988 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +0800989 layer->blending = blending[i];
990 layer->planeAlpha = planeAlpha[i];
991 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700992 }
993
Sushil Chauhandefd3522014-05-13 18:17:12 -0700994 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700995 // reset PTOR
996 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700997 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700998 } else {
999 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1000 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001001 }
1002
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001003 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1004 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001005 return result;
1006}
1007
Saurabh Shahaa236822013-04-24 18:07:26 -07001008bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1009{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001010 if(!sEnableMixedMode) {
1011 //Mixed mode is disabled. No need to even try caching.
1012 return false;
1013 }
1014
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001015 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001016 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001017 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001018 cacheBasedComp(ctx, list);
1019 } else {
1020 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001021 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001022 }
1023
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001024 return ret;
1025}
1026
1027bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1028 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001029 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1030 return false;
1031
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001032 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001033 mCurrentFrame.reset(numAppLayers);
1034 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001035
1036 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1037 for(int i = 0; i < numAppLayers; i++) {
1038 if(!mCurrentFrame.isFBComposed[i]) {
1039 hwc_layer_1_t* layer = &list->hwLayers[i];
1040 if(not isSupportedForMDPComp(ctx, layer)) {
1041 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1042 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001043 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001044 return false;
1045 }
1046 }
1047 }
1048
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001049 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301050 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001051 if(!ret) {
1052 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001053 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001054 return false;
1055 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001056
1057 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001058
Raj Kamal389d6e32014-08-04 14:43:24 +05301059 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001060 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301061 }
1062
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001063 //Will benefit cases where a video has non-updating background.
1064 if((mDpy > HWC_DISPLAY_PRIMARY) and
1065 (mdpCount > MAX_SEC_LAYERS)) {
1066 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001067 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001068 return false;
1069 }
1070
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001071 if(!postHeuristicsHandling(ctx, list)) {
1072 ALOGD_IF(isDebug(), "post heuristic handling failed");
1073 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001074 return false;
1075 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001076 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1077 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001078
Saurabh Shahaa236822013-04-24 18:07:26 -07001079 return true;
1080}
1081
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001082bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001083 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001084 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1085 return false;
1086
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001087 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001088 return false;
1089 }
1090
Saurabh Shahb772ae32013-11-18 15:40:02 -08001091 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001092 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1093 const int stagesForMDP = min(sMaxPipesPerMixer,
1094 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001095
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001096 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1097 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1098 int lastMDPSupportedIndex = numAppLayers;
1099 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001100
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001101 //Find the minimum MDP batch size
1102 for(int i = 0; i < numAppLayers;i++) {
1103 if(mCurrentFrame.drop[i]) {
1104 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001105 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001106 }
1107 hwc_layer_1_t* layer = &list->hwLayers[i];
1108 if(not isSupportedForMDPComp(ctx, layer)) {
1109 lastMDPSupportedIndex = i;
1110 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1111 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001112 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001113 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001114 }
1115
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001116 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1117 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1118 mCurrentFrame.dropCount);
1119
1120 //Start at a point where the fb batch should at least have 2 layers, for
1121 //this mode to be justified.
1122 while(fbBatchSize < 2) {
1123 ++fbBatchSize;
1124 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001125 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001126
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001127 //If there are no layers for MDP, this mode doesnt make sense.
1128 if(mdpBatchSize < 1) {
1129 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1130 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001131 return false;
1132 }
1133
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001134 mCurrentFrame.reset(numAppLayers);
1135
1136 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1137 while(mdpBatchSize > 0) {
1138 //Mark layers for MDP comp
1139 int mdpBatchLeft = mdpBatchSize;
1140 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1141 if(mCurrentFrame.drop[i]) {
1142 continue;
1143 }
1144 mCurrentFrame.isFBComposed[i] = false;
1145 --mdpBatchLeft;
1146 }
1147
1148 mCurrentFrame.fbZ = mdpBatchSize;
1149 mCurrentFrame.fbCount = fbBatchSize;
1150 mCurrentFrame.mdpCount = mdpBatchSize;
1151
1152 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1153 __FUNCTION__, mdpBatchSize, fbBatchSize,
1154 mCurrentFrame.dropCount);
1155
1156 if(postHeuristicsHandling(ctx, list)) {
1157 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001158 __FUNCTION__);
1159 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1160 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001161 return true;
1162 }
1163
1164 reset(ctx);
1165 --mdpBatchSize;
1166 ++fbBatchSize;
1167 }
1168
1169 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001170}
1171
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001172bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301173 if(mDpy or isSecurePresent(ctx, mDpy) or
1174 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001175 return false;
1176 }
1177 return true;
1178}
1179
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001180bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1181 hwc_display_contents_1_t* list){
1182 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1183 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1184 mDpy ) {
1185 return false;
1186 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001187 if(ctx->listStats[mDpy].secureUI)
1188 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001189 return true;
1190}
1191
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001192bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1193 hwc_display_contents_1_t* list) {
1194 const bool secureOnly = true;
1195 return videoOnlyComp(ctx, list, not secureOnly) or
1196 videoOnlyComp(ctx, list, secureOnly);
1197}
1198
1199bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001200 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001201 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1202 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001203 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001204
Saurabh Shahaa236822013-04-24 18:07:26 -07001205 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001206 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001207 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001208 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001209
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001210 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1211 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001212 return false;
1213 }
1214
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001215 /* Bail out if we are processing only secured video layers
1216 * and we dont have any */
1217 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001218 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001219 return false;
1220 }
1221
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001222 if(mCurrentFrame.fbCount)
1223 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001224
Raj Kamal389d6e32014-08-04 14:43:24 +05301225 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001226 adjustForSourceSplit(ctx, list);
1227 }
1228
1229 if(!postHeuristicsHandling(ctx, list)) {
1230 ALOGD_IF(isDebug(), "post heuristic handling failed");
1231 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001232 return false;
1233 }
1234
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001235 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1236 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001237 return true;
1238}
1239
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001240/* Checks for conditions where YUV layers cannot be bypassed */
1241bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001242 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001243 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001244 return false;
1245 }
1246
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001247 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001248 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1249 return false;
1250 }
1251
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001252 if(isSecuring(ctx, layer)) {
1253 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1254 return false;
1255 }
1256
Saurabh Shah4fdde762013-04-30 18:47:33 -07001257 if(!isValidDimension(ctx, layer)) {
1258 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1259 __FUNCTION__);
1260 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001261 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001262
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001263 if(layer->planeAlpha < 0xFF) {
1264 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1265 in video only mode",
1266 __FUNCTION__);
1267 return false;
1268 }
1269
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001270 return true;
1271}
1272
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301273/* starts at fromIndex and check for each layer to find
1274 * if it it has overlapping with any Updating layer above it in zorder
1275 * till the end of the batch. returns true if it finds any intersection */
1276bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1277 int fromIndex, int toIndex) {
1278 for(int i = fromIndex; i < toIndex; i++) {
1279 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1280 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1281 return false;
1282 }
1283 }
1284 }
1285 return true;
1286}
1287
1288/* Checks if given layer at targetLayerIndex has any
1289 * intersection with all the updating layers in beween
1290 * fromIndex and toIndex. Returns true if it finds intersectiion */
1291bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1292 int fromIndex, int toIndex, int targetLayerIndex) {
1293 for(int i = fromIndex; i <= toIndex; i++) {
1294 if(!mCurrentFrame.isFBComposed[i]) {
1295 if(areLayersIntersecting(&list->hwLayers[i],
1296 &list->hwLayers[targetLayerIndex])) {
1297 return true;
1298 }
1299 }
1300 }
1301 return false;
1302}
1303
1304int MDPComp::getBatch(hwc_display_contents_1_t* list,
1305 int& maxBatchStart, int& maxBatchEnd,
1306 int& maxBatchCount) {
1307 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301308 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001309 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301310 while (i < mCurrentFrame.layerCount) {
1311 int batchCount = 0;
1312 int batchStart = i;
1313 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001314 /* Adjust batch Z order with the dropped layers so far */
1315 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301316 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301317 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301318 while(i < mCurrentFrame.layerCount) {
1319 if(!mCurrentFrame.isFBComposed[i]) {
1320 if(!batchCount) {
1321 i++;
1322 break;
1323 }
1324 updatingLayersAbove++;
1325 i++;
1326 continue;
1327 } else {
1328 if(mCurrentFrame.drop[i]) {
1329 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001330 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301331 continue;
1332 } else if(updatingLayersAbove <= 0) {
1333 batchCount++;
1334 batchEnd = i;
1335 i++;
1336 continue;
1337 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1338
1339 // We have a valid updating layer already. If layer-i not
1340 // have overlapping with all updating layers in between
1341 // batch-start and i, then we can add layer i to batch.
1342 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1343 batchCount++;
1344 batchEnd = i;
1345 i++;
1346 continue;
1347 } else if(canPushBatchToTop(list, batchStart, i)) {
1348 //If All the non-updating layers with in this batch
1349 //does not have intersection with the updating layers
1350 //above in z-order, then we can safely move the batch to
1351 //higher z-order. Increment fbZ as it is moving up.
1352 if( firstZReverseIndex < 0) {
1353 firstZReverseIndex = i;
1354 }
1355 batchCount++;
1356 batchEnd = i;
1357 fbZ += updatingLayersAbove;
1358 i++;
1359 updatingLayersAbove = 0;
1360 continue;
1361 } else {
1362 //both failed.start the loop again from here.
1363 if(firstZReverseIndex >= 0) {
1364 i = firstZReverseIndex;
1365 }
1366 break;
1367 }
1368 }
1369 }
1370 }
1371 if(batchCount > maxBatchCount) {
1372 maxBatchCount = batchCount;
1373 maxBatchStart = batchStart;
1374 maxBatchEnd = batchEnd;
1375 fbZOrder = fbZ;
1376 }
1377 }
1378 return fbZOrder;
1379}
1380
1381bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1382 hwc_display_contents_1_t* list) {
1383 /* Idea is to keep as many non-updating(cached) layers in FB and
1384 * send rest of them through MDP. This is done in 2 steps.
1385 * 1. Find the maximum contiguous batch of non-updating layers.
1386 * 2. See if we can improve this batch size for caching by adding
1387 * opaque layers around the batch, if they don't have
1388 * any overlapping with the updating layers in between.
1389 * NEVER mark an updating layer for caching.
1390 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001391
1392 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001393 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001394 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301395 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001396
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001397 /* Nothing is cached. No batching needed */
1398 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001399 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001400 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001401
1402 /* No MDP comp layers, try to use other comp modes */
1403 if(mCurrentFrame.mdpCount == 0) {
1404 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001405 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001406
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301407 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001408
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301409 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001410 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001411 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001412 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301413 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001414 if(!mCurrentFrame.drop[i]){
1415 //If an unsupported layer is being attempted to
1416 //be pulled out we should fail
1417 if(not isSupportedForMDPComp(ctx, layer)) {
1418 return false;
1419 }
1420 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001421 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001422 }
1423 }
1424
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301425 // update the frame data
1426 mCurrentFrame.fbZ = fbZ;
1427 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001428 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001429 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001430
1431 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301432 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001433
1434 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001435}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001436
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001437void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001438 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001439 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001440 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001441
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001442 for(int i = 0; i < numAppLayers; i++) {
1443 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001444 if(!mCurrentFrame.drop[i])
1445 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001446 mCurrentFrame.isFBComposed[i] = true;
1447 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001448 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001449 }
1450 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001451
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001452 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001453 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1454 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001455
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001456 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1457 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1458 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001459}
1460
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001461void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1462 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001463 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1464 for(int index = 0;index < nYuvCount; index++){
1465 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1466 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1467
1468 if(!isYUVDoable(ctx, layer)) {
1469 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1470 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1471 mCurrentFrame.fbCount++;
1472 }
1473 } else {
1474 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001475 private_handle_t *hnd = (private_handle_t *)layer->handle;
1476 if(!secureOnly || isSecureBuffer(hnd)) {
1477 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1478 mCurrentFrame.fbCount--;
1479 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001480 }
1481 }
1482 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001483
1484 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001485 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1486 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001487 mCurrentFrame.fbCount);
1488}
1489
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001490hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1491 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001492 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001493
1494 /* Update only the region of FB needed for composition */
1495 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1496 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1497 hwc_layer_1_t* layer = &list->hwLayers[i];
1498 hwc_rect_t dst = layer->displayFrame;
1499 fbRect = getUnion(fbRect, dst);
1500 }
1501 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001502 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001503 return fbRect;
1504}
1505
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001506bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1507 hwc_display_contents_1_t* list) {
1508
1509 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001510 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001511 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1512 return false;
1513 }
1514
1515 //Limitations checks
1516 if(!hwLimitationsCheck(ctx, list)) {
1517 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1518 return false;
1519 }
1520
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001521 //Configure framebuffer first if applicable
1522 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001523 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001524 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1525 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001526 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1527 __FUNCTION__);
1528 return false;
1529 }
1530 }
1531
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001532 mCurrentFrame.map();
1533
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001534 if(!allocLayerPipes(ctx, list)) {
1535 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001536 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001537 }
1538
1539 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001540 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001541 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001542 int mdpIndex = mCurrentFrame.layerToMDP[index];
1543 hwc_layer_1_t* layer = &list->hwLayers[index];
1544
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301545 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1546 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1547 mdpNextZOrder++;
1548 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001549 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1550 cur_pipe->zOrder = mdpNextZOrder++;
1551
radhakrishnac9a67412013-09-25 17:40:42 +05301552 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301553 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301554 if(configure4k2kYuv(ctx, layer,
1555 mCurrentFrame.mdpToLayer[mdpIndex])
1556 != 0 ){
1557 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1558 for layer %d",__FUNCTION__, index);
1559 return false;
1560 }
1561 else{
1562 mdpNextZOrder++;
1563 }
1564 continue;
1565 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001566 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1567 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301568 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001569 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001570 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001571 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001572 }
1573
Saurabh Shaha36be922013-12-16 18:18:39 -08001574 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1575 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1576 ,__FUNCTION__, mDpy);
1577 return false;
1578 }
1579
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001580 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001581 return true;
1582}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001584bool MDPComp::resourceCheck(hwc_context_t* ctx,
1585 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001586 const bool fbUsed = mCurrentFrame.fbCount;
1587 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1588 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1589 return false;
1590 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001591 // Init rotCount to number of rotate sessions used by other displays
1592 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1593 // Count the number of rotator sessions required for current display
1594 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1595 if(!mCurrentFrame.isFBComposed[index]) {
1596 hwc_layer_1_t* layer = &list->hwLayers[index];
1597 private_handle_t *hnd = (private_handle_t *)layer->handle;
1598 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1599 rotCount++;
1600 }
1601 }
1602 }
1603 // if number of layers to rotate exceeds max rotator sessions, bail out.
1604 if(rotCount > RotMgr::MAX_ROT_SESS) {
1605 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1606 __FUNCTION__, mDpy);
1607 return false;
1608 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001609 return true;
1610}
1611
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301612bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1613 hwc_display_contents_1_t* list) {
1614
1615 //A-family hw limitation:
1616 //If a layer need alpha scaling, MDP can not support.
1617 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1618 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1619 if(!mCurrentFrame.isFBComposed[i] &&
1620 isAlphaScaled( &list->hwLayers[i])) {
1621 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1622 return false;
1623 }
1624 }
1625 }
1626
1627 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1628 //If multiple layers requires downscaling and also they are overlapping
1629 //fall back to GPU since MDSS can not handle it.
1630 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1631 qdutils::MDPVersion::getInstance().is8x26()) {
1632 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1633 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1634 if(!mCurrentFrame.isFBComposed[i] &&
1635 isDownscaleRequired(botLayer)) {
1636 //if layer-i is marked for MDP and needs downscaling
1637 //check if any MDP layer on top of i & overlaps with layer-i
1638 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1639 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1640 if(!mCurrentFrame.isFBComposed[j] &&
1641 isDownscaleRequired(topLayer)) {
1642 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1643 topLayer->displayFrame);
1644 if(isValidRect(r))
1645 return false;
1646 }
1647 }
1648 }
1649 }
1650 }
1651 return true;
1652}
1653
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001654int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001655 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001656 char property[PROPERTY_VALUE_MAX];
1657
Raj Kamal4393eaa2014-06-06 13:45:20 +05301658 if(!ctx || !list) {
1659 ALOGE("%s: Invalid context or list",__FUNCTION__);
1660 mCachedFrame.reset();
1661 return -1;
1662 }
1663
1664 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1665
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001666 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1667 int currentFlags = atoi(property);
1668 if(currentFlags != sSimulationFlags) {
1669 sSimulationFlags = currentFlags;
1670 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1671 sSimulationFlags, sSimulationFlags);
1672 }
1673 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001674 // reset PTOR
1675 if(!mDpy)
1676 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001677
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301678 //Do not cache the information for next draw cycle.
1679 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1680 ALOGI("%s: Unsupported layer count for mdp composition",
1681 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001682 mCachedFrame.reset();
1683 return -1;
1684 }
1685
Saurabh Shahb39f8152013-08-22 10:21:44 -07001686 //reset old data
1687 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001688 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1689 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301690
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001691 // Detect the start of animation and fall back to GPU only once to cache
1692 // all the layers in FB and display FB content untill animation completes.
1693 if(ctx->listStats[mDpy].isDisplayAnimating) {
1694 mCurrentFrame.needsRedraw = false;
1695 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1696 mCurrentFrame.needsRedraw = true;
1697 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1698 }
1699 setMDPCompLayerFlags(ctx, list);
1700 mCachedFrame.updateCounts(mCurrentFrame);
1701 ret = -1;
1702 return ret;
1703 } else {
1704 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1705 }
1706
Saurabh Shahb39f8152013-08-22 10:21:44 -07001707 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001708 if(isFrameDoable(ctx)) {
1709 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001710
Raj Kamal4393eaa2014-06-06 13:45:20 +05301711 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1712 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001713 setMDPCompLayerFlags(ctx, list);
1714 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001715 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001716 reset(ctx);
1717 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1718 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001719 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001720 }
1721 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001722 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1723 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001724 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001725 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001726
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001728 ALOGD("GEOMETRY change: %d",
1729 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001730 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001731 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001732 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001733 }
1734
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001735 mCachedFrame.cacheAll(list);
1736 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001737 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001738}
1739
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001740bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301741
1742 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301743 int mdpIndex = mCurrentFrame.layerToMDP[index];
1744 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1745 info.pipeInfo = new MdpYUVPipeInfo;
1746 info.rot = NULL;
1747 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301748
1749 pipe_info.lIndex = ovutils::OV_INVALID;
1750 pipe_info.rIndex = ovutils::OV_INVALID;
1751
Saurabh Shahc62f3982014-03-05 14:28:26 -08001752 Overlay::PipeSpecs pipeSpecs;
1753 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1754 pipeSpecs.needsScaling = true;
1755 pipeSpecs.dpy = mDpy;
1756 pipeSpecs.fb = false;
1757
1758 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301759 if(pipe_info.lIndex == ovutils::OV_INVALID){
1760 bRet = false;
1761 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1762 __FUNCTION__);
1763 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001764 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301765 if(pipe_info.rIndex == ovutils::OV_INVALID){
1766 bRet = false;
1767 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1768 __FUNCTION__);
1769 }
1770 return bRet;
1771}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001772
1773int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1774 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001775 if (ctx->mPtorInfo.isActive()) {
1776 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001777 if (fd < 0) {
1778 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001779 }
1780 }
1781 return fd;
1782}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001783//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001784
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001785void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301786 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001787 //If 4k2k Yuv layer split is possible, and if
1788 //fbz is above 4k2k layer, increment fb zorder by 1
1789 //as we split 4k2k layer and increment zorder for right half
1790 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001791 if(!ctx)
1792 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001793 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301794 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1795 index++) {
1796 if(!mCurrentFrame.isFBComposed[index]) {
1797 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1798 mdpNextZOrder++;
1799 }
1800 mdpNextZOrder++;
1801 hwc_layer_1_t* layer = &list->hwLayers[index];
1802 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301803 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301804 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1805 mCurrentFrame.fbZ += 1;
1806 mdpNextZOrder++;
1807 //As we split 4kx2k yuv layer and program to 2 VG pipes
1808 //(if available) increase mdpcount by 1.
1809 mCurrentFrame.mdpCount++;
1810 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001811 }
1812 }
1813 }
radhakrishnac9a67412013-09-25 17:40:42 +05301814}
1815
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001816/*
1817 * Configures pipe(s) for MDP composition
1818 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001819int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001820 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001821 MdpPipeInfoNonSplit& mdp_info =
1822 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001823 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1824 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1825 eIsFg isFg = IS_FG_OFF;
1826 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001827
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001828 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1829 __FUNCTION__, layer, zOrder, dest);
1830
Saurabh Shah88e4d272013-09-03 13:31:29 -07001831 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001832 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001833}
1834
Saurabh Shah88e4d272013-09-03 13:31:29 -07001835bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001836 hwc_display_contents_1_t* list) {
1837 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001838
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001839 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001840
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001841 hwc_layer_1_t* layer = &list->hwLayers[index];
1842 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301843 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001844 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301845 continue;
1846 }
1847 }
1848
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001849 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001850 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001851 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001852 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001853 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001854
Saurabh Shahc62f3982014-03-05 14:28:26 -08001855 Overlay::PipeSpecs pipeSpecs;
1856 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1857 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1858 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1859 (qdutils::MDPVersion::getInstance().is8x26() and
1860 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1861 pipeSpecs.dpy = mDpy;
1862 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001863 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001864
Saurabh Shahc62f3982014-03-05 14:28:26 -08001865 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1866
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001867 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001868 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001869 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001870 }
1871 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001872 return true;
1873}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001874
radhakrishnac9a67412013-09-25 17:40:42 +05301875int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1876 PipeLayerPair& PipeLayerPair) {
1877 MdpYUVPipeInfo& mdp_info =
1878 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1879 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1880 eIsFg isFg = IS_FG_OFF;
1881 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1882 eDest lDest = mdp_info.lIndex;
1883 eDest rDest = mdp_info.rIndex;
1884
1885 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1886 lDest, rDest, &PipeLayerPair.rot);
1887}
1888
Saurabh Shah88e4d272013-09-03 13:31:29 -07001889bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001890
Raj Kamal4393eaa2014-06-06 13:45:20 +05301891 if(!isEnabled() or !mModeOn) {
1892 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301893 return true;
1894 }
1895
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001896 // Set the Handle timeout to true for MDP or MIXED composition.
1897 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1898 sHandleTimeout = true;
1899 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001900
1901 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001902 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001903
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001904 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1905 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001906 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001907 if(mCurrentFrame.isFBComposed[i]) continue;
1908
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001909 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001910 private_handle_t *hnd = (private_handle_t *)layer->handle;
1911 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001912 if (!(layer->flags & HWC_COLOR_FILL)) {
1913 ALOGE("%s handle null", __FUNCTION__);
1914 return false;
1915 }
1916 // No PLAY for Color layer
1917 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1918 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001919 }
1920
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001921 int mdpIndex = mCurrentFrame.layerToMDP[i];
1922
Raj Kamal389d6e32014-08-04 14:43:24 +05301923 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05301924 {
1925 MdpYUVPipeInfo& pipe_info =
1926 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1927 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1928 ovutils::eDest indexL = pipe_info.lIndex;
1929 ovutils::eDest indexR = pipe_info.rIndex;
1930 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301931 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301932 if(rot) {
1933 rot->queueBuffer(fd, offset);
1934 fd = rot->getDstMemId();
1935 offset = rot->getDstOffset();
1936 }
1937 if(indexL != ovutils::OV_INVALID) {
1938 ovutils::eDest destL = (ovutils::eDest)indexL;
1939 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1940 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1941 if (!ov.queueBuffer(fd, offset, destL)) {
1942 ALOGE("%s: queueBuffer failed for display:%d",
1943 __FUNCTION__, mDpy);
1944 return false;
1945 }
1946 }
1947
1948 if(indexR != ovutils::OV_INVALID) {
1949 ovutils::eDest destR = (ovutils::eDest)indexR;
1950 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1951 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1952 if (!ov.queueBuffer(fd, offset, destR)) {
1953 ALOGE("%s: queueBuffer failed for display:%d",
1954 __FUNCTION__, mDpy);
1955 return false;
1956 }
1957 }
1958 }
1959 else{
1960 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001961 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301962 ovutils::eDest dest = pipe_info.index;
1963 if(dest == ovutils::OV_INVALID) {
1964 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001965 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301966 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001967
radhakrishnac9a67412013-09-25 17:40:42 +05301968 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1969 continue;
1970 }
1971
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001972 int fd = hnd->fd;
1973 uint32_t offset = (uint32_t)hnd->offset;
1974 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1975 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001976 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001977 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001978 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001979 }
1980
radhakrishnac9a67412013-09-25 17:40:42 +05301981 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1982 using pipe: %d", __FUNCTION__, layer,
1983 hnd, dest );
1984
radhakrishnac9a67412013-09-25 17:40:42 +05301985 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1986 if(rot) {
1987 if(!rot->queueBuffer(fd, offset))
1988 return false;
1989 fd = rot->getDstMemId();
1990 offset = rot->getDstOffset();
1991 }
1992
1993 if (!ov.queueBuffer(fd, offset, dest)) {
1994 ALOGE("%s: queueBuffer failed for display:%d ",
1995 __FUNCTION__, mDpy);
1996 return false;
1997 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001998 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001999
2000 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002001 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002002 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002003}
2004
Saurabh Shah88e4d272013-09-03 13:31:29 -07002005//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002006
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002007void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302008 hwc_display_contents_1_t* list){
2009 //if 4kx2k yuv layer is totally present in either in left half
2010 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302011 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302012 if(mCurrentFrame.fbZ >= 0) {
2013 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2014 index++) {
2015 if(!mCurrentFrame.isFBComposed[index]) {
2016 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2017 mdpNextZOrder++;
2018 }
2019 mdpNextZOrder++;
2020 hwc_layer_1_t* layer = &list->hwLayers[index];
2021 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302022 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302023 hwc_rect_t dst = layer->displayFrame;
2024 if((dst.left > lSplit) || (dst.right < lSplit)) {
2025 mCurrentFrame.mdpCount += 1;
2026 }
2027 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2028 mCurrentFrame.fbZ += 1;
2029 mdpNextZOrder++;
2030 }
2031 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002032 }
radhakrishnac9a67412013-09-25 17:40:42 +05302033 }
2034}
2035
Saurabh Shah88e4d272013-09-03 13:31:29 -07002036bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002037 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002038
Saurabh Shahc62f3982014-03-05 14:28:26 -08002039 const int lSplit = getLeftSplit(ctx, mDpy);
2040 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002041 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002042 pipe_info.lIndex = ovutils::OV_INVALID;
2043 pipe_info.rIndex = ovutils::OV_INVALID;
2044
Saurabh Shahc62f3982014-03-05 14:28:26 -08002045 Overlay::PipeSpecs pipeSpecs;
2046 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2047 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2048 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2049 pipeSpecs.dpy = mDpy;
2050 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2051 pipeSpecs.fb = false;
2052
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002053 // Acquire pipe only for the updating half
2054 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2055 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2056
2057 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002058 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002059 if(pipe_info.lIndex == ovutils::OV_INVALID)
2060 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002061 }
2062
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002063 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002064 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2065 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002066 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002067 return false;
2068 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002069
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002070 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002071}
2072
Saurabh Shah88e4d272013-09-03 13:31:29 -07002073bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002074 hwc_display_contents_1_t* list) {
2075 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002076
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002077 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002078
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002079 hwc_layer_1_t* layer = &list->hwLayers[index];
2080 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302081 hwc_rect_t dst = layer->displayFrame;
2082 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302083 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302084 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002085 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302086 continue;
2087 }
2088 }
2089 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002090 int mdpIndex = mCurrentFrame.layerToMDP[index];
2091 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002092 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002093 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002094 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002095
Saurabh Shahc62f3982014-03-05 14:28:26 -08002096 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2097 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2098 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002099 return false;
2100 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002101 }
2102 return true;
2103}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002104
radhakrishnac9a67412013-09-25 17:40:42 +05302105int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2106 PipeLayerPair& PipeLayerPair) {
2107 const int lSplit = getLeftSplit(ctx, mDpy);
2108 hwc_rect_t dst = layer->displayFrame;
2109 if((dst.left > lSplit)||(dst.right < lSplit)){
2110 MdpYUVPipeInfo& mdp_info =
2111 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2112 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2113 eIsFg isFg = IS_FG_OFF;
2114 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2115 eDest lDest = mdp_info.lIndex;
2116 eDest rDest = mdp_info.rIndex;
2117
2118 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2119 lDest, rDest, &PipeLayerPair.rot);
2120 }
2121 else{
2122 return configure(ctx, layer, PipeLayerPair);
2123 }
2124}
2125
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002126/*
2127 * Configures pipe(s) for MDP composition
2128 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002129int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002130 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002131 MdpPipeInfoSplit& mdp_info =
2132 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002133 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2134 eIsFg isFg = IS_FG_OFF;
2135 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2136 eDest lDest = mdp_info.lIndex;
2137 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002138
2139 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2140 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2141
Saurabh Shah88e4d272013-09-03 13:31:29 -07002142 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002143 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002144}
2145
Saurabh Shah88e4d272013-09-03 13:31:29 -07002146bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002147
Raj Kamal4393eaa2014-06-06 13:45:20 +05302148 if(!isEnabled() or !mModeOn) {
2149 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302150 return true;
2151 }
2152
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002153 // Set the Handle timeout to true for MDP or MIXED composition.
2154 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2155 sHandleTimeout = true;
2156 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002157
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002158 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002159 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002160
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002161 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2162 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002163 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002164 if(mCurrentFrame.isFBComposed[i]) continue;
2165
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002166 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002167 private_handle_t *hnd = (private_handle_t *)layer->handle;
2168 if(!hnd) {
2169 ALOGE("%s handle null", __FUNCTION__);
2170 return false;
2171 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002172
2173 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2174 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002175 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002176
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002177 int mdpIndex = mCurrentFrame.layerToMDP[i];
2178
Raj Kamal389d6e32014-08-04 14:43:24 +05302179 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302180 {
2181 MdpYUVPipeInfo& pipe_info =
2182 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2183 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2184 ovutils::eDest indexL = pipe_info.lIndex;
2185 ovutils::eDest indexR = pipe_info.rIndex;
2186 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302187 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302188 if(rot) {
2189 rot->queueBuffer(fd, offset);
2190 fd = rot->getDstMemId();
2191 offset = rot->getDstOffset();
2192 }
2193 if(indexL != ovutils::OV_INVALID) {
2194 ovutils::eDest destL = (ovutils::eDest)indexL;
2195 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2196 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2197 if (!ov.queueBuffer(fd, offset, destL)) {
2198 ALOGE("%s: queueBuffer failed for display:%d",
2199 __FUNCTION__, mDpy);
2200 return false;
2201 }
2202 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002203
radhakrishnac9a67412013-09-25 17:40:42 +05302204 if(indexR != ovutils::OV_INVALID) {
2205 ovutils::eDest destR = (ovutils::eDest)indexR;
2206 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2207 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2208 if (!ov.queueBuffer(fd, offset, destR)) {
2209 ALOGE("%s: queueBuffer failed for display:%d",
2210 __FUNCTION__, mDpy);
2211 return false;
2212 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002213 }
2214 }
radhakrishnac9a67412013-09-25 17:40:42 +05302215 else{
2216 MdpPipeInfoSplit& pipe_info =
2217 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2218 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002219
radhakrishnac9a67412013-09-25 17:40:42 +05302220 ovutils::eDest indexL = pipe_info.lIndex;
2221 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002222
radhakrishnac9a67412013-09-25 17:40:42 +05302223 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002224 uint32_t offset = (uint32_t)hnd->offset;
2225 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2226 if (!mDpy && (index != -1)) {
2227 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2228 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002229 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002230 }
radhakrishnac9a67412013-09-25 17:40:42 +05302231
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002232 if(ctx->mAD->draw(ctx, fd, offset)) {
2233 fd = ctx->mAD->getDstFd();
2234 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002235 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002236
radhakrishnac9a67412013-09-25 17:40:42 +05302237 if(rot) {
2238 rot->queueBuffer(fd, offset);
2239 fd = rot->getDstMemId();
2240 offset = rot->getDstOffset();
2241 }
2242
2243 //************* play left mixer **********
2244 if(indexL != ovutils::OV_INVALID) {
2245 ovutils::eDest destL = (ovutils::eDest)indexL;
2246 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2247 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2248 if (!ov.queueBuffer(fd, offset, destL)) {
2249 ALOGE("%s: queueBuffer failed for left mixer",
2250 __FUNCTION__);
2251 return false;
2252 }
2253 }
2254
2255 //************* play right mixer **********
2256 if(indexR != ovutils::OV_INVALID) {
2257 ovutils::eDest destR = (ovutils::eDest)indexR;
2258 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2259 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2260 if (!ov.queueBuffer(fd, offset, destR)) {
2261 ALOGE("%s: queueBuffer failed for right mixer",
2262 __FUNCTION__);
2263 return false;
2264 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002265 }
2266 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002267
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002268 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2269 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002270
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002271 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002272}
Saurabh Shahab47c692014-02-12 18:45:57 -08002273
2274//================MDPCompSrcSplit==============================================
2275bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002276 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002277 private_handle_t *hnd = (private_handle_t *)layer->handle;
2278 hwc_rect_t dst = layer->displayFrame;
2279 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2280 pipe_info.lIndex = ovutils::OV_INVALID;
2281 pipe_info.rIndex = ovutils::OV_INVALID;
2282
2283 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2284 //should have a higher priority than the right one. Pipe priorities are
2285 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002286
Saurabh Shahc62f3982014-03-05 14:28:26 -08002287 Overlay::PipeSpecs pipeSpecs;
2288 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2289 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2290 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2291 pipeSpecs.dpy = mDpy;
2292 pipeSpecs.fb = false;
2293
Saurabh Shahab47c692014-02-12 18:45:57 -08002294 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002295 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002296 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002297 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002298 }
2299
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002300 /* Use 2 pipes IF
2301 a) Layer's crop width is > 2048 or
2302 b) Layer's dest width > 2048 or
2303 c) On primary, driver has indicated with caps to split always. This is
2304 based on an empirically derived value of panel height. Applied only
2305 if the layer's width is > mixer's width
2306 */
2307
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302308 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002309 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302310 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002311 int lSplit = getLeftSplit(ctx, mDpy);
2312 int dstWidth = dst.right - dst.left;
2313 int cropWidth = crop.right - crop.left;
2314
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002315 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2316 //pipe line length, we are still using 2 pipes. This is fine just because
2317 //this is source split where destination doesn't matter. Evaluate later to
2318 //see if going through all the calcs to save a pipe is worth it
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302319 if(dstWidth > mdpHw.getMaxMixerWidth() or
2320 cropWidth > mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002321 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002322 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002323 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002324 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002325 }
2326
2327 // Return values
2328 // 1 Left pipe is higher priority, do nothing.
2329 // 0 Pipes of same priority.
2330 //-1 Right pipe is of higher priority, needs swap.
2331 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2332 pipe_info.rIndex) == -1) {
2333 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002334 }
2335 }
2336
2337 return true;
2338}
2339
Saurabh Shahab47c692014-02-12 18:45:57 -08002340int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2341 PipeLayerPair& PipeLayerPair) {
2342 private_handle_t *hnd = (private_handle_t *)layer->handle;
2343 if(!hnd) {
2344 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2345 return -1;
2346 }
2347 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2348 MdpPipeInfoSplit& mdp_info =
2349 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2350 Rotator **rot = &PipeLayerPair.rot;
2351 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2352 eIsFg isFg = IS_FG_OFF;
2353 eDest lDest = mdp_info.lIndex;
2354 eDest rDest = mdp_info.rIndex;
2355 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2356 hwc_rect_t dst = layer->displayFrame;
2357 int transform = layer->transform;
2358 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002359 int rotFlags = ROT_FLAGS_NONE;
2360 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2361 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2362
2363 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2364 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2365
2366 // Handle R/B swap
2367 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2368 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2369 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2370 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2371 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2372 }
2373
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002374 int downscale = getRotDownscale(ctx, layer);
Saurabh Shah97e2d802014-04-14 18:03:54 -07002375 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002376 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002377
2378 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2379 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002380 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002381 }
2382
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002383 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002384 (*rot) = ctx->mRotMgr->getNext();
2385 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002386 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002387 //If the video is using a single pipe, enable BWC
2388 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002389 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002390 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002391 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002392 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002393 ALOGE("%s: configRotator failed!", __FUNCTION__);
2394 return -1;
2395 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002396 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002397 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002398 }
2399
2400 //If 2 pipes being used, divide layer into half, crop and dst
2401 hwc_rect_t cropL = crop;
2402 hwc_rect_t cropR = crop;
2403 hwc_rect_t dstL = dst;
2404 hwc_rect_t dstR = dst;
2405 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2406 cropL.right = (crop.right + crop.left) / 2;
2407 cropR.left = cropL.right;
2408 sanitizeSourceCrop(cropL, cropR, hnd);
2409
2410 //Swap crops on H flip since 2 pipes are being used
2411 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2412 hwc_rect_t tmp = cropL;
2413 cropL = cropR;
2414 cropR = tmp;
2415 }
2416
2417 dstL.right = (dst.right + dst.left) / 2;
2418 dstR.left = dstL.right;
2419 }
2420
2421 //For the mdp, since either we are pre-rotating or MDP does flips
2422 orient = OVERLAY_TRANSFORM_0;
2423 transform = 0;
2424
2425 //configure left pipe
2426 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002427 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002428 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2429 (ovutils::eBlending) getBlending(layer->blending));
2430
2431 if(configMdp(ctx->mOverlay, pargL, orient,
2432 cropL, dstL, metadata, lDest) < 0) {
2433 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2434 return -1;
2435 }
2436 }
2437
2438 //configure right pipe
2439 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002440 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002441 static_cast<eRotFlags>(rotFlags),
2442 layer->planeAlpha,
2443 (ovutils::eBlending) getBlending(layer->blending));
2444 if(configMdp(ctx->mOverlay, pargR, orient,
2445 cropR, dstR, metadata, rDest) < 0) {
2446 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2447 return -1;
2448 }
2449 }
2450
2451 return 0;
2452}
2453
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002454}; //namespace
2455