blob: 35c5dc2dd2c6ff85a4eeb21883603218a3a77b44 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
radhakrishnac9a67412013-09-25 17:40:42 +053048bool MDPComp::sEnable4k2kYUVSplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
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() &&
159 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
160 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
161 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
radhakrishnac9a67412013-09-25 17:40:42 +0530162 sEnable4k2kYUVSplit = true;
163 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700164
165 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
166 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
167 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
169 HWC_DISPLAY_PRIMARY);
170 }
171
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700172 return true;
173}
174
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800175void MDPComp::reset(hwc_context_t *ctx) {
176 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700177 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800178 ctx->mOverlay->clear(mDpy);
179 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700180}
181
Raj Kamal4393eaa2014-06-06 13:45:20 +0530182void MDPComp::reset() {
183 sHandleTimeout = false;
184 mModeOn = false;
185}
186
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700187void MDPComp::timeout_handler(void *udata) {
188 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
189
190 if(!ctx) {
191 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
192 return;
193 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800194 Locker::Autolock _l(ctx->mDrawLock);
195 // Handle timeout event only if the previous composition is MDP or MIXED.
196 if(!sHandleTimeout) {
197 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
198 return;
199 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700200 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700201 ALOGE("%s: HWC proc not registered", __FUNCTION__);
202 return;
203 }
204 sIdleFallBack = true;
205 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700206 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700207}
208
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800209void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800210 hwc_display_contents_1_t* list) {
211 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800212
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800213 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 if(!mCurrentFrame.isFBComposed[index]) {
216 layerProp[index].mFlags |= HWC_MDPCOMP;
217 layer->compositionType = HWC_OVERLAY;
218 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800219 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700220 /* Drop the layer when its already present in FB OR when it lies
221 * outside frame's ROI */
222 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700224 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800225 }
226 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500228
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800229void MDPComp::setRedraw(hwc_context_t *ctx,
230 hwc_display_contents_1_t* list) {
231 mCurrentFrame.needsRedraw = false;
232 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
233 (list->flags & HWC_GEOMETRY_CHANGED) ||
234 isSkipPresent(ctx, mDpy)) {
235 mCurrentFrame.needsRedraw = true;
236 }
237}
238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700240 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800242
Saurabh Shahaa236822013-04-24 18:07:26 -0700243void MDPComp::FrameInfo::reset(const int& numLayers) {
244 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245 if(mdpToLayer[i].pipeInfo) {
246 delete mdpToLayer[i].pipeInfo;
247 mdpToLayer[i].pipeInfo = NULL;
248 //We dont own the rotator
249 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800250 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800251 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800252
253 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
254 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700255 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800256
Saurabh Shahaa236822013-04-24 18:07:26 -0700257 layerCount = numLayers;
258 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800259 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700260 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800261 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800262}
263
Saurabh Shahaa236822013-04-24 18:07:26 -0700264void MDPComp::FrameInfo::map() {
265 // populate layer and MDP maps
266 int mdpIdx = 0;
267 for(int idx = 0; idx < layerCount; idx++) {
268 if(!isFBComposed[idx]) {
269 mdpToLayer[mdpIdx].listIndex = idx;
270 layerToMDP[idx] = mdpIdx++;
271 }
272 }
273}
274
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800275MDPComp::LayerCache::LayerCache() {
276 reset();
277}
278
279void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700280 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530281 memset(&isFBComposed, true, sizeof(isFBComposed));
282 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700284}
285
286void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530287 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700288 for(int i = 0; i < numAppLayers; i++) {
289 hnd[i] = list->hwLayers[i].handle;
290 }
291}
292
293void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700294 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530295 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
296 memcpy(&drop, &curFrame.drop, sizeof(drop));
297}
298
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800299bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
300 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530301 if(layerCount != curFrame.layerCount)
302 return false;
303 for(int i = 0; i < curFrame.layerCount; i++) {
304 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
305 (curFrame.drop[i] != drop[i])) {
306 return false;
307 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800308 if(curFrame.isFBComposed[i] &&
309 (hnd[i] != list->hwLayers[i].handle)){
310 return false;
311 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530312 }
313 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800314}
315
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700316bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
317 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800318 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700319 (not isValidDimension(ctx,layer))
320 //More conditions here, SKIP, sRGB+Blend etc
321 ) {
322 return false;
323 }
324 return true;
325}
326
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530327bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800328 private_handle_t *hnd = (private_handle_t *)layer->handle;
329
330 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700331 if (layer->flags & HWC_COLOR_FILL) {
332 // Color layer
333 return true;
334 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800335 ALOGE("%s: layer handle is NULL", __FUNCTION__);
336 return false;
337 }
338
Naseer Ahmede850a802013-09-06 13:12:52 -0400339 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400340 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400341 return false;
342
Saurabh Shah62e1d732013-09-17 10:44:05 -0700343 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700344 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700345 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700346 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
347 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700348 int dst_w = dst.right - dst.left;
349 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800350 float w_scale = ((float)crop_w / (float)dst_w);
351 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700352
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800353 /* Workaround for MDP HW limitation in DSI command mode panels where
354 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
355 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530356 * There also is a HW limilation in MDP, minimum block size is 2x2
357 * Fallback to GPU if height is less than 2.
358 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800359 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800360 return false;
361
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800362 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700363 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700364 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800365 const float w_dscale = w_scale;
366 const float h_dscale = h_scale;
367
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800368 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700369
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800370 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700371 /* On targets that doesnt support Decimation (eg.,8x26)
372 * maximum downscale support is overlay pipe downscale.
373 */
374 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
375 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800376 return false;
377 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700378 // Decimation on macrotile format layers is not supported.
379 if(isTileRendered(hnd)) {
380 /* MDP can read maximum MAX_DISPLAY_DIM width.
381 * Bail out if
382 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
383 * 2. exceeds maximum downscale limit
384 */
385 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
386 w_dscale > maxMDPDownscale ||
387 h_dscale > maxMDPDownscale) {
388 return false;
389 }
390 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800391 return false;
392 }
393 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700394 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700395 return false;
396 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700397 }
398
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800399 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
400 const uint32_t upscale =
401 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
402 const float w_uscale = 1.0f / w_scale;
403 const float h_uscale = 1.0f / h_scale;
404
405 if(w_uscale > upscale || h_uscale > upscale)
406 return false;
407 }
408
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800409 return true;
410}
411
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800412bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700413 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800414
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800415 if(!isEnabled()) {
416 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700417 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530418 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530419 qdutils::MDPVersion::getInstance().is8x16() ||
420 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800421 ctx->mVideoTransFlag &&
422 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700423 //1 Padding round to shift pipes across mixers
424 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
425 __FUNCTION__);
426 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800427 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800428 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800429 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700430 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700431 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530432 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
433 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700434 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700435 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800437}
438
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800439void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
440 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
441 fbRect = getIntersection(fbRect, roi);
442}
443
444/* 1) Identify layers that are not visible or lying outside the updating ROI and
445 * drop them from composition.
446 * 2) If we have a scaling layer which needs cropping against generated
447 * ROI, reset ROI to full resolution. */
448bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
449 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700450 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800451 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800452
453 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800454 if(!isValidRect(visibleRect)) {
455 mCurrentFrame.drop[i] = true;
456 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800457 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800458 }
459
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700460 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700461 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800462 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700463
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700464 if(!isValidRect(res)) {
465 mCurrentFrame.drop[i] = true;
466 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800467 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468 /* Reset frame ROI when any layer which needs scaling also needs ROI
469 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800470 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800471 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
473 mCurrentFrame.dropCount = 0;
474 return false;
475 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800476
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800477 /* deduct any opaque region from visibleRect */
478 if (layer->blending == HWC_BLENDING_NONE)
479 visibleRect = deductRect(visibleRect, res);
480 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700481 }
482 return true;
483}
484
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800485/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
486 * are updating. If DirtyRegion is applicable, calculate it by accounting all
487 * the changing layer's dirtyRegion. */
488void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
489 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700490 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800491 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700492 return;
493
494 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800495 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
496 (int)ctx->dpyAttr[mDpy].yres};
497
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800499 hwc_layer_1_t* layer = &list->hwLayers[index];
500 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800501 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700502 hwc_rect_t dst = layer->displayFrame;
503 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800504
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800505#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800506 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700507 {
508 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
509 int x_off = dst.left - src.left;
510 int y_off = dst.top - src.top;
511 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
512 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800513#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800514
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800515 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700516 }
517 }
518
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519 /* No layer is updating. Still SF wants a refresh.*/
520 if(!isValidRect(roi))
521 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800522
523 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800524 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800525
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800526 ctx->listStats[mDpy].lRoi = roi;
527 if(!validateAndApplyROI(ctx, list))
528 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529
530 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800531 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
532 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
533}
534
535void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
536 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
537 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
538
539 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
540 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
541 fbRect = getUnion(l_fbRect, r_fbRect);
542}
543/* 1) Identify layers that are not visible or lying outside BOTH the updating
544 * ROI's and drop them from composition. If a layer is spanning across both
545 * the halves of the screen but needed by only ROI, the non-contributing
546 * half will not be programmed for MDP.
547 * 2) If we have a scaling layer which needs cropping against generated
548 * ROI, reset ROI to full resolution. */
549bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
550 hwc_display_contents_1_t* list) {
551
552 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
553
554 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
555 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
556
557 for(int i = numAppLayers - 1; i >= 0; i--){
558 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
559 {
560 mCurrentFrame.drop[i] = true;
561 mCurrentFrame.dropCount++;
562 continue;
563 }
564
565 const hwc_layer_1_t* layer = &list->hwLayers[i];
566 hwc_rect_t dstRect = layer->displayFrame;
567
568 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
569 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
570 hwc_rect_t res = getUnion(l_res, r_res);
571
572 if(!isValidRect(l_res) && !isValidRect(r_res)) {
573 mCurrentFrame.drop[i] = true;
574 mCurrentFrame.dropCount++;
575 } else {
576 /* Reset frame ROI when any layer which needs scaling also needs ROI
577 * cropping */
578 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
579 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
580 mCurrentFrame.dropCount = 0;
581 return false;
582 }
583
584 if (layer->blending == HWC_BLENDING_NONE) {
585 visibleRectL = deductRect(visibleRectL, l_res);
586 visibleRectR = deductRect(visibleRectR, r_res);
587 }
588 }
589 }
590 return true;
591}
592/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
593 * are updating. If DirtyRegion is applicable, calculate it by accounting all
594 * the changing layer's dirtyRegion. */
595void MDPCompSplit::generateROI(hwc_context_t *ctx,
596 hwc_display_contents_1_t* list) {
597 if(!canPartialUpdate(ctx, list))
598 return;
599
600 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
601 int lSplit = getLeftSplit(ctx, mDpy);
602
603 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
604 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
605
606 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
607 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
608
609 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
610 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
611
612 for(int index = 0; index < numAppLayers; index++ ) {
613 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800614 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800615 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800616 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700617 hwc_rect_t dst = layer->displayFrame;
618 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800619
620#ifdef QCOM_BSP
621 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700622 {
623 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
624 int x_off = dst.left - src.left;
625 int y_off = dst.top - src.top;
626 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
627 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800628#endif
629
630 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
631 if(isValidRect(l_dst))
632 l_roi = getUnion(l_roi, l_dst);
633
634 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
635 if(isValidRect(r_dst))
636 r_roi = getUnion(r_roi, r_dst);
637 }
638 }
639
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700640 /* For panels that cannot accept commands in both the interfaces, we cannot
641 * send two ROI's (for each half). We merge them into single ROI and split
642 * them across lSplit for MDP mixer use. The ROI's will be merged again
643 * finally before udpating the panel in the driver. */
644 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
645 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
646 l_roi = getIntersection(temp_roi, l_frame);
647 r_roi = getIntersection(temp_roi, r_frame);
648 }
649
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800650 /* No layer is updating. Still SF wants a refresh. */
651 if(!isValidRect(l_roi) && !isValidRect(r_roi))
652 return;
653
654 l_roi = getSanitizeROI(l_roi, l_frame);
655 r_roi = getSanitizeROI(r_roi, r_frame);
656
657 ctx->listStats[mDpy].lRoi = l_roi;
658 ctx->listStats[mDpy].rRoi = r_roi;
659
660 if(!validateAndApplyROI(ctx, list))
661 resetROI(ctx, mDpy);
662
663 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
664 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
665 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
666 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
667 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
668 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700669}
670
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800671/* Checks for conditions where all the layers marked for MDP comp cannot be
672 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800673bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800674 hwc_display_contents_1_t* list){
675
Saurabh Shahaa236822013-04-24 18:07:26 -0700676 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800677 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800678
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700679 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700680 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
681 return false;
682 }
683
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800684 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700685 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
686 __FUNCTION__,
687 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800688 return false;
689 }
690
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800691 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
692 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
693 // Disable MDP comp on Secondary when the primary is highres panel and
694 // the secondary is a normal 1080p, because, MDP comp on secondary under
695 // in such usecase, decimation gets used for downscale and there will be
696 // a quality mismatch when there will be a fallback to GPU comp
697 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
698 __FUNCTION__);
699 return false;
700 }
701
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800702 // check for action safe flag and downscale mode which requires scaling.
703 if(ctx->dpyAttr[mDpy].mActionSafePresent
704 || ctx->dpyAttr[mDpy].mDownScaleMode) {
705 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
706 return false;
707 }
708
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800709 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800710 hwc_layer_1_t* layer = &list->hwLayers[i];
711 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800712
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800713 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700714 if(!canUseRotator(ctx, mDpy)) {
715 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
716 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700717 return false;
718 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800719 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530720
721 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
722 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700723 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530724 if(qdutils::MDPVersion::getInstance().is8x26() &&
725 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700726 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530727 (!isYuvBuffer(hnd)))
728 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800729 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700730
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700731 if(ctx->mAD->isDoable()) {
732 return false;
733 }
734
Saurabh Shahaa236822013-04-24 18:07:26 -0700735 //If all above hard conditions are met we can do full or partial MDP comp.
736 bool ret = false;
737 if(fullMDPComp(ctx, list)) {
738 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700739 } else if(fullMDPCompWithPTOR(ctx, list)) {
740 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700741 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700742 ret = true;
743 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530744
Saurabh Shahaa236822013-04-24 18:07:26 -0700745 return ret;
746}
747
748bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700749
750 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
751 return false;
752
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700753 //Will benefit presentation / secondary-only layer.
754 if((mDpy > HWC_DISPLAY_PRIMARY) &&
755 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
756 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
757 return false;
758 }
759
760 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
761 for(int i = 0; i < numAppLayers; i++) {
762 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700763 if(not mCurrentFrame.drop[i] and
764 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700765 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
766 return false;
767 }
768 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800769
Saurabh Shahaa236822013-04-24 18:07:26 -0700770 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700771 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
772 sizeof(mCurrentFrame.isFBComposed));
773 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
774 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700775
radhakrishnac9a67412013-09-25 17:40:42 +0530776 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800777 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530778 }
779
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800780 if(!postHeuristicsHandling(ctx, list)) {
781 ALOGD_IF(isDebug(), "post heuristic handling failed");
782 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700783 return false;
784 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700785 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
786 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700787 return true;
788}
789
Sushil Chauhandefd3522014-05-13 18:17:12 -0700790/* Full MDP Composition with Peripheral Tiny Overlap Removal.
791 * MDP bandwidth limitations can be avoided, if the overlap region
792 * covered by the smallest layer at a higher z-order, gets composed
793 * by Copybit on a render buffer, which can be queued to MDP.
794 */
795bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
796 hwc_display_contents_1_t* list) {
797
798 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
799 const int stagesForMDP = min(sMaxPipesPerMixer,
800 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
801
802 // Hard checks where we cannot use this mode
803 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
804 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
805 return false;
806 }
807
808 // Frame level checks
809 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
810 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
811 isSecurePresent(ctx, mDpy)) {
812 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
813 return false;
814 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700815 // MDP comp checks
816 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700817 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700818 if(not isSupportedForMDPComp(ctx, layer)) {
819 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
820 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700821 }
822 }
823
Sushil Chauhandefd3522014-05-13 18:17:12 -0700824 /* We cannot use this composition mode, if:
825 1. A below layer needs scaling.
826 2. Overlap is not peripheral to display.
827 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700828 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700829 */
830
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700831 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
832 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
833 memset(overlapRect, 0, sizeof(overlapRect));
834 int layerPixelCount, minPixelCount = 0;
835 int numPTORLayersFound = 0;
836 for (int i = numAppLayers-1; (i >= 0 &&
837 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700838 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700839 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700841 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
842 // PTOR layer should be peripheral and cannot have transform
843 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
844 has90Transform(layer)) {
845 continue;
846 }
847 if((3 * (layerPixelCount + minPixelCount)) >
848 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
849 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
850 continue;
851 }
852 // Found the PTOR layer
853 bool found = true;
854 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;
858 //layer below PTOR is intersecting and has 90 degree transform or
859 // needs scaling cannot be supported.
860 if ((isValidRect(getIntersection(dispFrame, disFrame)))
861 && (has90Transform(layer) || needsScaling(layer))) {
862 found = false;
863 break;
864 }
865 }
866 // Store the minLayer Index
867 if(found) {
868 minLayerIndex[numPTORLayersFound] = i;
869 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
870 minPixelCount += layerPixelCount;
871 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700872 }
873 }
874
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700875 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
876 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
877 __FUNCTION__);
878 // reset second minLayerIndex[1];
879 minLayerIndex[1] = -1;
880 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700881 }
882
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700883 // No overlap layers
884 if (!numPTORLayersFound)
885 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700887 ctx->mPtorInfo.count = numPTORLayersFound;
888 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
889 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
890 }
891
892 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
893 // reset PTOR
894 ctx->mPtorInfo.count = 0;
895 return false;
896 }
897 // Store the displayFrame and the sourceCrops of the layers
898 hwc_rect_t displayFrame[numAppLayers];
899 hwc_rect_t sourceCrop[numAppLayers];
900 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700901 hwc_layer_1_t* layer = &list->hwLayers[i];
902 displayFrame[i] = layer->displayFrame;
903 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700904 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700905
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 for(int j = 0; j < numPTORLayersFound; j++) {
907 int index = ctx->mPtorInfo.layerIndex[j];
908 // Remove overlap from crop & displayFrame of below layers
909 for (int i = 0; i < index && index !=-1; i++) {
910 hwc_layer_1_t* layer = &list->hwLayers[i];
911 if(!isValidRect(getIntersection(layer->displayFrame,
912 overlapRect[j]))) {
913 continue;
914 }
915 // Update layer attributes
916 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
917 hwc_rect_t destRect = deductRect(layer->displayFrame,
918 overlapRect[j]);
919 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
920 layer->transform);
921 layer->sourceCropf.left = (float)srcCrop.left;
922 layer->sourceCropf.top = (float)srcCrop.top;
923 layer->sourceCropf.right = (float)srcCrop.right;
924 layer->sourceCropf.bottom = (float)srcCrop.bottom;
925 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700926 }
927
928 mCurrentFrame.mdpCount = numAppLayers;
929 mCurrentFrame.fbCount = 0;
930 mCurrentFrame.fbZ = -1;
931
932 for (int j = 0; j < numAppLayers; j++)
933 mCurrentFrame.isFBComposed[j] = false;
934
935 bool result = postHeuristicsHandling(ctx, list);
936
937 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700939 hwc_layer_1_t* layer = &list->hwLayers[i];
940 layer->displayFrame = displayFrame[i];
941 layer->sourceCropf.left = (float)sourceCrop[i].left;
942 layer->sourceCropf.top = (float)sourceCrop[i].top;
943 layer->sourceCropf.right = (float)sourceCrop[i].right;
944 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
945 }
946
947 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700948 // reset PTOR
949 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700950 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 } else {
952 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
953 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700954 }
955
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
957 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -0700958 return result;
959}
960
Saurabh Shahaa236822013-04-24 18:07:26 -0700961bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
962{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700963 if(!sEnableMixedMode) {
964 //Mixed mode is disabled. No need to even try caching.
965 return false;
966 }
967
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700968 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800969 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800970 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800971 cacheBasedComp(ctx, list);
972 } else {
973 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800974 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700975 }
976
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700977 return ret;
978}
979
980bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
981 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700982 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
983 return false;
984
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700985 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700986 mCurrentFrame.reset(numAppLayers);
987 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700988
989 //If an MDP marked layer is unsupported cannot do partial MDP Comp
990 for(int i = 0; i < numAppLayers; i++) {
991 if(!mCurrentFrame.isFBComposed[i]) {
992 hwc_layer_1_t* layer = &list->hwLayers[i];
993 if(not isSupportedForMDPComp(ctx, layer)) {
994 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
995 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800996 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700997 return false;
998 }
999 }
1000 }
1001
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001002 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301003 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001004 if(!ret) {
1005 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001006 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001007 return false;
1008 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001009
1010 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001011
radhakrishnac9a67412013-09-25 17:40:42 +05301012 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001013 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301014 }
1015
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001016 //Will benefit cases where a video has non-updating background.
1017 if((mDpy > HWC_DISPLAY_PRIMARY) and
1018 (mdpCount > MAX_SEC_LAYERS)) {
1019 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001020 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001021 return false;
1022 }
1023
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001024 if(!postHeuristicsHandling(ctx, list)) {
1025 ALOGD_IF(isDebug(), "post heuristic handling failed");
1026 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001027 return false;
1028 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001029 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1030 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001031
Saurabh Shahaa236822013-04-24 18:07:26 -07001032 return true;
1033}
1034
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001035bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001036 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001037 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1038 return false;
1039
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001040 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001041 return false;
1042 }
1043
Saurabh Shahb772ae32013-11-18 15:40:02 -08001044 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001045 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1046 const int stagesForMDP = min(sMaxPipesPerMixer,
1047 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001048
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001049 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1050 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1051 int lastMDPSupportedIndex = numAppLayers;
1052 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001053
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001054 //Find the minimum MDP batch size
1055 for(int i = 0; i < numAppLayers;i++) {
1056 if(mCurrentFrame.drop[i]) {
1057 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001058 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001059 }
1060 hwc_layer_1_t* layer = &list->hwLayers[i];
1061 if(not isSupportedForMDPComp(ctx, layer)) {
1062 lastMDPSupportedIndex = i;
1063 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1064 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001065 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001066 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001067 }
1068
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001069 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1070 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1071 mCurrentFrame.dropCount);
1072
1073 //Start at a point where the fb batch should at least have 2 layers, for
1074 //this mode to be justified.
1075 while(fbBatchSize < 2) {
1076 ++fbBatchSize;
1077 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001078 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001079
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001080 //If there are no layers for MDP, this mode doesnt make sense.
1081 if(mdpBatchSize < 1) {
1082 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1083 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001084 return false;
1085 }
1086
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001087 mCurrentFrame.reset(numAppLayers);
1088
1089 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1090 while(mdpBatchSize > 0) {
1091 //Mark layers for MDP comp
1092 int mdpBatchLeft = mdpBatchSize;
1093 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1094 if(mCurrentFrame.drop[i]) {
1095 continue;
1096 }
1097 mCurrentFrame.isFBComposed[i] = false;
1098 --mdpBatchLeft;
1099 }
1100
1101 mCurrentFrame.fbZ = mdpBatchSize;
1102 mCurrentFrame.fbCount = fbBatchSize;
1103 mCurrentFrame.mdpCount = mdpBatchSize;
1104
1105 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1106 __FUNCTION__, mdpBatchSize, fbBatchSize,
1107 mCurrentFrame.dropCount);
1108
1109 if(postHeuristicsHandling(ctx, list)) {
1110 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001111 __FUNCTION__);
1112 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1113 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001114 return true;
1115 }
1116
1117 reset(ctx);
1118 --mdpBatchSize;
1119 ++fbBatchSize;
1120 }
1121
1122 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001123}
1124
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001125bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301126 if(mDpy or isSecurePresent(ctx, mDpy) or
1127 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001128 return false;
1129 }
1130 return true;
1131}
1132
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001133bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1134 hwc_display_contents_1_t* list){
1135 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1136 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1137 mDpy ) {
1138 return false;
1139 }
1140 return true;
1141}
1142
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001143bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1144 hwc_display_contents_1_t* list) {
1145 const bool secureOnly = true;
1146 return videoOnlyComp(ctx, list, not secureOnly) or
1147 videoOnlyComp(ctx, list, secureOnly);
1148}
1149
1150bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001151 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001152 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1153 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001154 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001155
Saurabh Shahaa236822013-04-24 18:07:26 -07001156 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001157 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001158 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001159 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001160
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001161 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1162 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001163 return false;
1164 }
1165
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001166 /* Bail out if we are processing only secured video layers
1167 * and we dont have any */
1168 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001169 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001170 return false;
1171 }
1172
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001173 if(mCurrentFrame.fbCount)
1174 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001175
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001176 if(sEnable4k2kYUVSplit){
1177 adjustForSourceSplit(ctx, list);
1178 }
1179
1180 if(!postHeuristicsHandling(ctx, list)) {
1181 ALOGD_IF(isDebug(), "post heuristic handling failed");
1182 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001183 return false;
1184 }
1185
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001186 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1187 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001188 return true;
1189}
1190
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001191/* Checks for conditions where YUV layers cannot be bypassed */
1192bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001193 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001194 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001195 return false;
1196 }
1197
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001198 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001199 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1200 return false;
1201 }
1202
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001203 if(isSecuring(ctx, layer)) {
1204 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1205 return false;
1206 }
1207
Saurabh Shah4fdde762013-04-30 18:47:33 -07001208 if(!isValidDimension(ctx, layer)) {
1209 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1210 __FUNCTION__);
1211 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001212 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001213
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001214 if(layer->planeAlpha < 0xFF) {
1215 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1216 in video only mode",
1217 __FUNCTION__);
1218 return false;
1219 }
1220
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001221 return true;
1222}
1223
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301224/* starts at fromIndex and check for each layer to find
1225 * if it it has overlapping with any Updating layer above it in zorder
1226 * till the end of the batch. returns true if it finds any intersection */
1227bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1228 int fromIndex, int toIndex) {
1229 for(int i = fromIndex; i < toIndex; i++) {
1230 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1231 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1232 return false;
1233 }
1234 }
1235 }
1236 return true;
1237}
1238
1239/* Checks if given layer at targetLayerIndex has any
1240 * intersection with all the updating layers in beween
1241 * fromIndex and toIndex. Returns true if it finds intersectiion */
1242bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1243 int fromIndex, int toIndex, int targetLayerIndex) {
1244 for(int i = fromIndex; i <= toIndex; i++) {
1245 if(!mCurrentFrame.isFBComposed[i]) {
1246 if(areLayersIntersecting(&list->hwLayers[i],
1247 &list->hwLayers[targetLayerIndex])) {
1248 return true;
1249 }
1250 }
1251 }
1252 return false;
1253}
1254
1255int MDPComp::getBatch(hwc_display_contents_1_t* list,
1256 int& maxBatchStart, int& maxBatchEnd,
1257 int& maxBatchCount) {
1258 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301259 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001260 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301261 while (i < mCurrentFrame.layerCount) {
1262 int batchCount = 0;
1263 int batchStart = i;
1264 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001265 /* Adjust batch Z order with the dropped layers so far */
1266 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301267 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301268 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301269 while(i < mCurrentFrame.layerCount) {
1270 if(!mCurrentFrame.isFBComposed[i]) {
1271 if(!batchCount) {
1272 i++;
1273 break;
1274 }
1275 updatingLayersAbove++;
1276 i++;
1277 continue;
1278 } else {
1279 if(mCurrentFrame.drop[i]) {
1280 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001281 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301282 continue;
1283 } else if(updatingLayersAbove <= 0) {
1284 batchCount++;
1285 batchEnd = i;
1286 i++;
1287 continue;
1288 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1289
1290 // We have a valid updating layer already. If layer-i not
1291 // have overlapping with all updating layers in between
1292 // batch-start and i, then we can add layer i to batch.
1293 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1294 batchCount++;
1295 batchEnd = i;
1296 i++;
1297 continue;
1298 } else if(canPushBatchToTop(list, batchStart, i)) {
1299 //If All the non-updating layers with in this batch
1300 //does not have intersection with the updating layers
1301 //above in z-order, then we can safely move the batch to
1302 //higher z-order. Increment fbZ as it is moving up.
1303 if( firstZReverseIndex < 0) {
1304 firstZReverseIndex = i;
1305 }
1306 batchCount++;
1307 batchEnd = i;
1308 fbZ += updatingLayersAbove;
1309 i++;
1310 updatingLayersAbove = 0;
1311 continue;
1312 } else {
1313 //both failed.start the loop again from here.
1314 if(firstZReverseIndex >= 0) {
1315 i = firstZReverseIndex;
1316 }
1317 break;
1318 }
1319 }
1320 }
1321 }
1322 if(batchCount > maxBatchCount) {
1323 maxBatchCount = batchCount;
1324 maxBatchStart = batchStart;
1325 maxBatchEnd = batchEnd;
1326 fbZOrder = fbZ;
1327 }
1328 }
1329 return fbZOrder;
1330}
1331
1332bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1333 hwc_display_contents_1_t* list) {
1334 /* Idea is to keep as many non-updating(cached) layers in FB and
1335 * send rest of them through MDP. This is done in 2 steps.
1336 * 1. Find the maximum contiguous batch of non-updating layers.
1337 * 2. See if we can improve this batch size for caching by adding
1338 * opaque layers around the batch, if they don't have
1339 * any overlapping with the updating layers in between.
1340 * NEVER mark an updating layer for caching.
1341 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001342
1343 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001344 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001345 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301346 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001347
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001348 /* Nothing is cached. No batching needed */
1349 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001350 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001351 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001352
1353 /* No MDP comp layers, try to use other comp modes */
1354 if(mCurrentFrame.mdpCount == 0) {
1355 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001356 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001357
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301358 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001359
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301360 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001361 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001362 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001363 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301364 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001365 if(!mCurrentFrame.drop[i]){
1366 //If an unsupported layer is being attempted to
1367 //be pulled out we should fail
1368 if(not isSupportedForMDPComp(ctx, layer)) {
1369 return false;
1370 }
1371 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001372 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001373 }
1374 }
1375
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301376 // update the frame data
1377 mCurrentFrame.fbZ = fbZ;
1378 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001379 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001380 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001381
1382 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301383 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001384
1385 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001386}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001387
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001388void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001389 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001390 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001391 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001392
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001393 for(int i = 0; i < numAppLayers; i++) {
1394 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001395 if(!mCurrentFrame.drop[i])
1396 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001397 mCurrentFrame.isFBComposed[i] = true;
1398 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001399 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001400 }
1401 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001402
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001403 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001404 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1405 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001406
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001407 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1408 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1409 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001410}
1411
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001412void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1413 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001414 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1415 for(int index = 0;index < nYuvCount; index++){
1416 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1417 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1418
1419 if(!isYUVDoable(ctx, layer)) {
1420 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1421 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1422 mCurrentFrame.fbCount++;
1423 }
1424 } else {
1425 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001426 private_handle_t *hnd = (private_handle_t *)layer->handle;
1427 if(!secureOnly || isSecureBuffer(hnd)) {
1428 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1429 mCurrentFrame.fbCount--;
1430 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001431 }
1432 }
1433 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001434
1435 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001436 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1437 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001438 mCurrentFrame.fbCount);
1439}
1440
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001441hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1442 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001443 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001444
1445 /* Update only the region of FB needed for composition */
1446 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1447 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1448 hwc_layer_1_t* layer = &list->hwLayers[i];
1449 hwc_rect_t dst = layer->displayFrame;
1450 fbRect = getUnion(fbRect, dst);
1451 }
1452 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001453 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001454 return fbRect;
1455}
1456
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001457bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1458 hwc_display_contents_1_t* list) {
1459
1460 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001461 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001462 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1463 return false;
1464 }
1465
1466 //Limitations checks
1467 if(!hwLimitationsCheck(ctx, list)) {
1468 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1469 return false;
1470 }
1471
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001472 //Configure framebuffer first if applicable
1473 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001474 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001475 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1476 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001477 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1478 __FUNCTION__);
1479 return false;
1480 }
1481 }
1482
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001483 mCurrentFrame.map();
1484
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001485 if(!allocLayerPipes(ctx, list)) {
1486 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001487 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001488 }
1489
1490 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001491 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001492 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001493 int mdpIndex = mCurrentFrame.layerToMDP[index];
1494 hwc_layer_1_t* layer = &list->hwLayers[index];
1495
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301496 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1497 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1498 mdpNextZOrder++;
1499 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001500 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1501 cur_pipe->zOrder = mdpNextZOrder++;
1502
radhakrishnac9a67412013-09-25 17:40:42 +05301503 private_handle_t *hnd = (private_handle_t *)layer->handle;
1504 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1505 if(configure4k2kYuv(ctx, layer,
1506 mCurrentFrame.mdpToLayer[mdpIndex])
1507 != 0 ){
1508 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1509 for layer %d",__FUNCTION__, index);
1510 return false;
1511 }
1512 else{
1513 mdpNextZOrder++;
1514 }
1515 continue;
1516 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001517 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1518 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301519 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001520 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001521 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001522 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001523 }
1524
Saurabh Shaha36be922013-12-16 18:18:39 -08001525 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1526 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1527 ,__FUNCTION__, mDpy);
1528 return false;
1529 }
1530
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001531 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001532 return true;
1533}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001534
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001535bool MDPComp::resourceCheck(hwc_context_t* ctx,
1536 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001537 const bool fbUsed = mCurrentFrame.fbCount;
1538 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1539 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1540 return false;
1541 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001542 // Init rotCount to number of rotate sessions used by other displays
1543 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1544 // Count the number of rotator sessions required for current display
1545 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1546 if(!mCurrentFrame.isFBComposed[index]) {
1547 hwc_layer_1_t* layer = &list->hwLayers[index];
1548 private_handle_t *hnd = (private_handle_t *)layer->handle;
1549 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1550 rotCount++;
1551 }
1552 }
1553 }
1554 // if number of layers to rotate exceeds max rotator sessions, bail out.
1555 if(rotCount > RotMgr::MAX_ROT_SESS) {
1556 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1557 __FUNCTION__, mDpy);
1558 return false;
1559 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001560 return true;
1561}
1562
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301563bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1564 hwc_display_contents_1_t* list) {
1565
1566 //A-family hw limitation:
1567 //If a layer need alpha scaling, MDP can not support.
1568 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1569 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1570 if(!mCurrentFrame.isFBComposed[i] &&
1571 isAlphaScaled( &list->hwLayers[i])) {
1572 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1573 return false;
1574 }
1575 }
1576 }
1577
1578 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1579 //If multiple layers requires downscaling and also they are overlapping
1580 //fall back to GPU since MDSS can not handle it.
1581 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1582 qdutils::MDPVersion::getInstance().is8x26()) {
1583 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1584 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1585 if(!mCurrentFrame.isFBComposed[i] &&
1586 isDownscaleRequired(botLayer)) {
1587 //if layer-i is marked for MDP and needs downscaling
1588 //check if any MDP layer on top of i & overlaps with layer-i
1589 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1590 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1591 if(!mCurrentFrame.isFBComposed[j] &&
1592 isDownscaleRequired(topLayer)) {
1593 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1594 topLayer->displayFrame);
1595 if(isValidRect(r))
1596 return false;
1597 }
1598 }
1599 }
1600 }
1601 }
1602 return true;
1603}
1604
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001605int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001606 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001607 char property[PROPERTY_VALUE_MAX];
1608
Raj Kamal4393eaa2014-06-06 13:45:20 +05301609 if(!ctx || !list) {
1610 ALOGE("%s: Invalid context or list",__FUNCTION__);
1611 mCachedFrame.reset();
1612 return -1;
1613 }
1614
1615 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1616
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001617 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1618 int currentFlags = atoi(property);
1619 if(currentFlags != sSimulationFlags) {
1620 sSimulationFlags = currentFlags;
1621 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1622 sSimulationFlags, sSimulationFlags);
1623 }
1624 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001625 // reset PTOR
1626 if(!mDpy)
1627 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001628
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301629 //Do not cache the information for next draw cycle.
1630 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1631 ALOGI("%s: Unsupported layer count for mdp composition",
1632 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001633 mCachedFrame.reset();
1634 return -1;
1635 }
1636
Saurabh Shahb39f8152013-08-22 10:21:44 -07001637 //reset old data
1638 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001639 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1640 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301641
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001642 // Detect the start of animation and fall back to GPU only once to cache
1643 // all the layers in FB and display FB content untill animation completes.
1644 if(ctx->listStats[mDpy].isDisplayAnimating) {
1645 mCurrentFrame.needsRedraw = false;
1646 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1647 mCurrentFrame.needsRedraw = true;
1648 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1649 }
1650 setMDPCompLayerFlags(ctx, list);
1651 mCachedFrame.updateCounts(mCurrentFrame);
1652 ret = -1;
1653 return ret;
1654 } else {
1655 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1656 }
1657
Saurabh Shahb39f8152013-08-22 10:21:44 -07001658 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001659 if(isFrameDoable(ctx)) {
1660 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001661
Raj Kamal4393eaa2014-06-06 13:45:20 +05301662 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1663 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001664 setMDPCompLayerFlags(ctx, list);
1665 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001666 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001667 reset(ctx);
1668 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1669 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001670 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001671 }
1672 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001673 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1674 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001675 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001676 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001677
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001679 ALOGD("GEOMETRY change: %d",
1680 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001682 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001683 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001684 }
1685
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001686 mCachedFrame.cacheAll(list);
1687 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001688 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001689}
1690
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001691bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301692
1693 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301694 int mdpIndex = mCurrentFrame.layerToMDP[index];
1695 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1696 info.pipeInfo = new MdpYUVPipeInfo;
1697 info.rot = NULL;
1698 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301699
1700 pipe_info.lIndex = ovutils::OV_INVALID;
1701 pipe_info.rIndex = ovutils::OV_INVALID;
1702
Saurabh Shahc62f3982014-03-05 14:28:26 -08001703 Overlay::PipeSpecs pipeSpecs;
1704 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1705 pipeSpecs.needsScaling = true;
1706 pipeSpecs.dpy = mDpy;
1707 pipeSpecs.fb = false;
1708
1709 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301710 if(pipe_info.lIndex == ovutils::OV_INVALID){
1711 bRet = false;
1712 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1713 __FUNCTION__);
1714 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001715 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301716 if(pipe_info.rIndex == ovutils::OV_INVALID){
1717 bRet = false;
1718 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1719 __FUNCTION__);
1720 }
1721 return bRet;
1722}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001723
1724int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1725 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001726 if (ctx->mPtorInfo.isActive()) {
1727 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001728 if (fd < 0) {
1729 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001730 }
1731 }
1732 return fd;
1733}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001734//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001735
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001736void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301737 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001738 //If 4k2k Yuv layer split is possible, and if
1739 //fbz is above 4k2k layer, increment fb zorder by 1
1740 //as we split 4k2k layer and increment zorder for right half
1741 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001742 if(!ctx)
1743 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001744 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301745 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1746 index++) {
1747 if(!mCurrentFrame.isFBComposed[index]) {
1748 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1749 mdpNextZOrder++;
1750 }
1751 mdpNextZOrder++;
1752 hwc_layer_1_t* layer = &list->hwLayers[index];
1753 private_handle_t *hnd = (private_handle_t *)layer->handle;
1754 if(is4kx2kYuvBuffer(hnd)) {
1755 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1756 mCurrentFrame.fbZ += 1;
1757 mdpNextZOrder++;
1758 //As we split 4kx2k yuv layer and program to 2 VG pipes
1759 //(if available) increase mdpcount by 1.
1760 mCurrentFrame.mdpCount++;
1761 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001762 }
1763 }
1764 }
radhakrishnac9a67412013-09-25 17:40:42 +05301765}
1766
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001767/*
1768 * Configures pipe(s) for MDP composition
1769 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001770int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001771 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001772 MdpPipeInfoNonSplit& mdp_info =
1773 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001774 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1775 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1776 eIsFg isFg = IS_FG_OFF;
1777 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001778
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001779 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1780 __FUNCTION__, layer, zOrder, dest);
1781
Saurabh Shah88e4d272013-09-03 13:31:29 -07001782 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001783 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001784}
1785
Saurabh Shah88e4d272013-09-03 13:31:29 -07001786bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001787 hwc_display_contents_1_t* list) {
1788 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001789
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001790 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001791
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001792 hwc_layer_1_t* layer = &list->hwLayers[index];
1793 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301794 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001795 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301796 continue;
1797 }
1798 }
1799
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001800 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001801 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001802 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001803 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001804 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001805
Saurabh Shahc62f3982014-03-05 14:28:26 -08001806 Overlay::PipeSpecs pipeSpecs;
1807 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1808 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1809 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1810 (qdutils::MDPVersion::getInstance().is8x26() and
1811 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1812 pipeSpecs.dpy = mDpy;
1813 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001814 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001815
Saurabh Shahc62f3982014-03-05 14:28:26 -08001816 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1817
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001818 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001819 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001820 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001821 }
1822 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001823 return true;
1824}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001825
radhakrishnac9a67412013-09-25 17:40:42 +05301826int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1827 PipeLayerPair& PipeLayerPair) {
1828 MdpYUVPipeInfo& mdp_info =
1829 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1830 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1831 eIsFg isFg = IS_FG_OFF;
1832 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1833 eDest lDest = mdp_info.lIndex;
1834 eDest rDest = mdp_info.rIndex;
1835
1836 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1837 lDest, rDest, &PipeLayerPair.rot);
1838}
1839
Saurabh Shah88e4d272013-09-03 13:31:29 -07001840bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001841
Raj Kamal4393eaa2014-06-06 13:45:20 +05301842 if(!isEnabled() or !mModeOn) {
1843 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301844 return true;
1845 }
1846
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001847 // Set the Handle timeout to true for MDP or MIXED composition.
1848 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1849 sHandleTimeout = true;
1850 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001851
1852 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001853 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001854
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001855 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1856 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001857 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001858 if(mCurrentFrame.isFBComposed[i]) continue;
1859
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001860 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001861 private_handle_t *hnd = (private_handle_t *)layer->handle;
1862 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001863 if (!(layer->flags & HWC_COLOR_FILL)) {
1864 ALOGE("%s handle null", __FUNCTION__);
1865 return false;
1866 }
1867 // No PLAY for Color layer
1868 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1869 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001870 }
1871
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001872 int mdpIndex = mCurrentFrame.layerToMDP[i];
1873
radhakrishnac9a67412013-09-25 17:40:42 +05301874 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1875 {
1876 MdpYUVPipeInfo& pipe_info =
1877 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1878 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1879 ovutils::eDest indexL = pipe_info.lIndex;
1880 ovutils::eDest indexR = pipe_info.rIndex;
1881 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301882 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301883 if(rot) {
1884 rot->queueBuffer(fd, offset);
1885 fd = rot->getDstMemId();
1886 offset = rot->getDstOffset();
1887 }
1888 if(indexL != ovutils::OV_INVALID) {
1889 ovutils::eDest destL = (ovutils::eDest)indexL;
1890 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1891 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1892 if (!ov.queueBuffer(fd, offset, destL)) {
1893 ALOGE("%s: queueBuffer failed for display:%d",
1894 __FUNCTION__, mDpy);
1895 return false;
1896 }
1897 }
1898
1899 if(indexR != ovutils::OV_INVALID) {
1900 ovutils::eDest destR = (ovutils::eDest)indexR;
1901 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1902 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1903 if (!ov.queueBuffer(fd, offset, destR)) {
1904 ALOGE("%s: queueBuffer failed for display:%d",
1905 __FUNCTION__, mDpy);
1906 return false;
1907 }
1908 }
1909 }
1910 else{
1911 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001912 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301913 ovutils::eDest dest = pipe_info.index;
1914 if(dest == ovutils::OV_INVALID) {
1915 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001916 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301917 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001918
radhakrishnac9a67412013-09-25 17:40:42 +05301919 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1920 continue;
1921 }
1922
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001923 int fd = hnd->fd;
1924 uint32_t offset = (uint32_t)hnd->offset;
1925 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1926 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001927 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001928 fd = hnd->fd;
1929 // Use the offset of the RenderBuffer
1930 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
Sushil Chauhandefd3522014-05-13 18:17:12 -07001931 }
1932
radhakrishnac9a67412013-09-25 17:40:42 +05301933 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1934 using pipe: %d", __FUNCTION__, layer,
1935 hnd, dest );
1936
radhakrishnac9a67412013-09-25 17:40:42 +05301937 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1938 if(rot) {
1939 if(!rot->queueBuffer(fd, offset))
1940 return false;
1941 fd = rot->getDstMemId();
1942 offset = rot->getDstOffset();
1943 }
1944
1945 if (!ov.queueBuffer(fd, offset, dest)) {
1946 ALOGE("%s: queueBuffer failed for display:%d ",
1947 __FUNCTION__, mDpy);
1948 return false;
1949 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001950 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001951
1952 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001953 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001954 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001955}
1956
Saurabh Shah88e4d272013-09-03 13:31:29 -07001957//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001958
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001959void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301960 hwc_display_contents_1_t* list){
1961 //if 4kx2k yuv layer is totally present in either in left half
1962 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301963 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301964 if(mCurrentFrame.fbZ >= 0) {
1965 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1966 index++) {
1967 if(!mCurrentFrame.isFBComposed[index]) {
1968 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1969 mdpNextZOrder++;
1970 }
1971 mdpNextZOrder++;
1972 hwc_layer_1_t* layer = &list->hwLayers[index];
1973 private_handle_t *hnd = (private_handle_t *)layer->handle;
1974 if(is4kx2kYuvBuffer(hnd)) {
1975 hwc_rect_t dst = layer->displayFrame;
1976 if((dst.left > lSplit) || (dst.right < lSplit)) {
1977 mCurrentFrame.mdpCount += 1;
1978 }
1979 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1980 mCurrentFrame.fbZ += 1;
1981 mdpNextZOrder++;
1982 }
1983 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001984 }
radhakrishnac9a67412013-09-25 17:40:42 +05301985 }
1986}
1987
Saurabh Shah88e4d272013-09-03 13:31:29 -07001988bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001989 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001990
Saurabh Shahc62f3982014-03-05 14:28:26 -08001991 const int lSplit = getLeftSplit(ctx, mDpy);
1992 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001993 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001994 pipe_info.lIndex = ovutils::OV_INVALID;
1995 pipe_info.rIndex = ovutils::OV_INVALID;
1996
Saurabh Shahc62f3982014-03-05 14:28:26 -08001997 Overlay::PipeSpecs pipeSpecs;
1998 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1999 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2000 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2001 pipeSpecs.dpy = mDpy;
2002 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2003 pipeSpecs.fb = false;
2004
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002005 // Acquire pipe only for the updating half
2006 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2007 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2008
2009 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002010 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002011 if(pipe_info.lIndex == ovutils::OV_INVALID)
2012 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002013 }
2014
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002015 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002016 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2017 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002018 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002019 return false;
2020 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002021
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002022 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002023}
2024
Saurabh Shah88e4d272013-09-03 13:31:29 -07002025bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002026 hwc_display_contents_1_t* list) {
2027 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002028
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002029 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002030
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002031 hwc_layer_1_t* layer = &list->hwLayers[index];
2032 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302033 hwc_rect_t dst = layer->displayFrame;
2034 const int lSplit = getLeftSplit(ctx, mDpy);
2035 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
2036 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002037 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302038 continue;
2039 }
2040 }
2041 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002042 int mdpIndex = mCurrentFrame.layerToMDP[index];
2043 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002044 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002045 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002046 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002047
Saurabh Shahc62f3982014-03-05 14:28:26 -08002048 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2049 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2050 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002051 return false;
2052 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002053 }
2054 return true;
2055}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002056
radhakrishnac9a67412013-09-25 17:40:42 +05302057int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2058 PipeLayerPair& PipeLayerPair) {
2059 const int lSplit = getLeftSplit(ctx, mDpy);
2060 hwc_rect_t dst = layer->displayFrame;
2061 if((dst.left > lSplit)||(dst.right < lSplit)){
2062 MdpYUVPipeInfo& mdp_info =
2063 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2064 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2065 eIsFg isFg = IS_FG_OFF;
2066 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2067 eDest lDest = mdp_info.lIndex;
2068 eDest rDest = mdp_info.rIndex;
2069
2070 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2071 lDest, rDest, &PipeLayerPair.rot);
2072 }
2073 else{
2074 return configure(ctx, layer, PipeLayerPair);
2075 }
2076}
2077
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002078/*
2079 * Configures pipe(s) for MDP composition
2080 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002081int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002082 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002083 MdpPipeInfoSplit& mdp_info =
2084 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002085 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2086 eIsFg isFg = IS_FG_OFF;
2087 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2088 eDest lDest = mdp_info.lIndex;
2089 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002090
2091 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2092 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2093
Saurabh Shah88e4d272013-09-03 13:31:29 -07002094 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002095 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002096}
2097
Saurabh Shah88e4d272013-09-03 13:31:29 -07002098bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002099
Raj Kamal4393eaa2014-06-06 13:45:20 +05302100 if(!isEnabled() or !mModeOn) {
2101 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302102 return true;
2103 }
2104
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002105 // Set the Handle timeout to true for MDP or MIXED composition.
2106 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2107 sHandleTimeout = true;
2108 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002109
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002110 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002111 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002112
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002113 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2114 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002115 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002116 if(mCurrentFrame.isFBComposed[i]) continue;
2117
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002118 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002119 private_handle_t *hnd = (private_handle_t *)layer->handle;
2120 if(!hnd) {
2121 ALOGE("%s handle null", __FUNCTION__);
2122 return false;
2123 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002124
2125 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2126 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002127 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002128
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002129 int mdpIndex = mCurrentFrame.layerToMDP[i];
2130
radhakrishnac9a67412013-09-25 17:40:42 +05302131 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2132 {
2133 MdpYUVPipeInfo& pipe_info =
2134 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2135 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2136 ovutils::eDest indexL = pipe_info.lIndex;
2137 ovutils::eDest indexR = pipe_info.rIndex;
2138 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302139 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302140 if(rot) {
2141 rot->queueBuffer(fd, offset);
2142 fd = rot->getDstMemId();
2143 offset = rot->getDstOffset();
2144 }
2145 if(indexL != ovutils::OV_INVALID) {
2146 ovutils::eDest destL = (ovutils::eDest)indexL;
2147 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2148 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2149 if (!ov.queueBuffer(fd, offset, destL)) {
2150 ALOGE("%s: queueBuffer failed for display:%d",
2151 __FUNCTION__, mDpy);
2152 return false;
2153 }
2154 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002155
radhakrishnac9a67412013-09-25 17:40:42 +05302156 if(indexR != ovutils::OV_INVALID) {
2157 ovutils::eDest destR = (ovutils::eDest)indexR;
2158 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2159 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2160 if (!ov.queueBuffer(fd, offset, destR)) {
2161 ALOGE("%s: queueBuffer failed for display:%d",
2162 __FUNCTION__, mDpy);
2163 return false;
2164 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002165 }
2166 }
radhakrishnac9a67412013-09-25 17:40:42 +05302167 else{
2168 MdpPipeInfoSplit& pipe_info =
2169 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2170 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002171
radhakrishnac9a67412013-09-25 17:40:42 +05302172 ovutils::eDest indexL = pipe_info.lIndex;
2173 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002174
radhakrishnac9a67412013-09-25 17:40:42 +05302175 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002176 uint32_t offset = (uint32_t)hnd->offset;
2177 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2178 if (!mDpy && (index != -1)) {
2179 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2180 fd = hnd->fd;
2181 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
2182 }
radhakrishnac9a67412013-09-25 17:40:42 +05302183
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002184 if(ctx->mAD->draw(ctx, fd, offset)) {
2185 fd = ctx->mAD->getDstFd();
2186 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002187 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002188
radhakrishnac9a67412013-09-25 17:40:42 +05302189 if(rot) {
2190 rot->queueBuffer(fd, offset);
2191 fd = rot->getDstMemId();
2192 offset = rot->getDstOffset();
2193 }
2194
2195 //************* play left mixer **********
2196 if(indexL != ovutils::OV_INVALID) {
2197 ovutils::eDest destL = (ovutils::eDest)indexL;
2198 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2199 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2200 if (!ov.queueBuffer(fd, offset, destL)) {
2201 ALOGE("%s: queueBuffer failed for left mixer",
2202 __FUNCTION__);
2203 return false;
2204 }
2205 }
2206
2207 //************* play right mixer **********
2208 if(indexR != ovutils::OV_INVALID) {
2209 ovutils::eDest destR = (ovutils::eDest)indexR;
2210 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2211 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2212 if (!ov.queueBuffer(fd, offset, destR)) {
2213 ALOGE("%s: queueBuffer failed for right mixer",
2214 __FUNCTION__);
2215 return false;
2216 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002217 }
2218 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002219
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002220 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2221 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002222
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002223 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002224}
Saurabh Shahab47c692014-02-12 18:45:57 -08002225
2226//================MDPCompSrcSplit==============================================
2227bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002228 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002229 private_handle_t *hnd = (private_handle_t *)layer->handle;
2230 hwc_rect_t dst = layer->displayFrame;
2231 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2232 pipe_info.lIndex = ovutils::OV_INVALID;
2233 pipe_info.rIndex = ovutils::OV_INVALID;
2234
2235 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2236 //should have a higher priority than the right one. Pipe priorities are
2237 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002238
Saurabh Shahc62f3982014-03-05 14:28:26 -08002239 Overlay::PipeSpecs pipeSpecs;
2240 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2241 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2242 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2243 pipeSpecs.dpy = mDpy;
2244 pipeSpecs.fb = false;
2245
Saurabh Shahab47c692014-02-12 18:45:57 -08002246 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002247 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002248 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002249 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002250 }
2251
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002252 /* Use 2 pipes IF
2253 a) Layer's crop width is > 2048 or
2254 b) Layer's dest width > 2048 or
2255 c) On primary, driver has indicated with caps to split always. This is
2256 based on an empirically derived value of panel height. Applied only
2257 if the layer's width is > mixer's width
2258 */
2259
2260 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2261 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2262 int lSplit = getLeftSplit(ctx, mDpy);
2263 int dstWidth = dst.right - dst.left;
2264 int cropWidth = crop.right - crop.left;
2265
2266 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2267 cropWidth > qdutils::MAX_DISPLAY_DIM or
2268 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002269 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002270 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002271 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002272 }
2273
2274 // Return values
2275 // 1 Left pipe is higher priority, do nothing.
2276 // 0 Pipes of same priority.
2277 //-1 Right pipe is of higher priority, needs swap.
2278 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2279 pipe_info.rIndex) == -1) {
2280 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002281 }
2282 }
2283
2284 return true;
2285}
2286
Saurabh Shahab47c692014-02-12 18:45:57 -08002287int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2288 PipeLayerPair& PipeLayerPair) {
2289 private_handle_t *hnd = (private_handle_t *)layer->handle;
2290 if(!hnd) {
2291 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2292 return -1;
2293 }
2294 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2295 MdpPipeInfoSplit& mdp_info =
2296 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2297 Rotator **rot = &PipeLayerPair.rot;
2298 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2299 eIsFg isFg = IS_FG_OFF;
2300 eDest lDest = mdp_info.lIndex;
2301 eDest rDest = mdp_info.rIndex;
2302 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2303 hwc_rect_t dst = layer->displayFrame;
2304 int transform = layer->transform;
2305 eTransform orient = static_cast<eTransform>(transform);
2306 const int downscale = 0;
2307 int rotFlags = ROT_FLAGS_NONE;
2308 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2309 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2310
2311 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2312 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2313
2314 // Handle R/B swap
2315 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2316 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2317 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2318 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2319 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2320 }
2321
Saurabh Shah97e2d802014-04-14 18:03:54 -07002322 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002323 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002324
2325 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2326 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002327 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002328 }
2329
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002330 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002331 (*rot) = ctx->mRotMgr->getNext();
2332 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002333 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002334 //If the video is using a single pipe, enable BWC
2335 if(rDest == OV_INVALID) {
2336 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2337 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002338 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002339 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002340 ALOGE("%s: configRotator failed!", __FUNCTION__);
2341 return -1;
2342 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002343 updateSource(orient, whf, crop, *rot);
Saurabh Shahab47c692014-02-12 18:45:57 -08002344 rotFlags |= ROT_PREROTATED;
2345 }
2346
2347 //If 2 pipes being used, divide layer into half, crop and dst
2348 hwc_rect_t cropL = crop;
2349 hwc_rect_t cropR = crop;
2350 hwc_rect_t dstL = dst;
2351 hwc_rect_t dstR = dst;
2352 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2353 cropL.right = (crop.right + crop.left) / 2;
2354 cropR.left = cropL.right;
2355 sanitizeSourceCrop(cropL, cropR, hnd);
2356
2357 //Swap crops on H flip since 2 pipes are being used
2358 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2359 hwc_rect_t tmp = cropL;
2360 cropL = cropR;
2361 cropR = tmp;
2362 }
2363
2364 dstL.right = (dst.right + dst.left) / 2;
2365 dstR.left = dstL.right;
2366 }
2367
2368 //For the mdp, since either we are pre-rotating or MDP does flips
2369 orient = OVERLAY_TRANSFORM_0;
2370 transform = 0;
2371
2372 //configure left pipe
2373 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002374 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002375 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2376 (ovutils::eBlending) getBlending(layer->blending));
2377
2378 if(configMdp(ctx->mOverlay, pargL, orient,
2379 cropL, dstL, metadata, lDest) < 0) {
2380 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2381 return -1;
2382 }
2383 }
2384
2385 //configure right pipe
2386 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002387 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002388 static_cast<eRotFlags>(rotFlags),
2389 layer->planeAlpha,
2390 (ovutils::eBlending) getBlending(layer->blending));
2391 if(configMdp(ctx->mOverlay, pargR, orient,
2392 cropR, dstR, metadata, rDest) < 0) {
2393 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2394 return -1;
2395 }
2396 }
2397
2398 return 0;
2399}
2400
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002401}; //namespace
2402