blob: 37b211d99d1b9be9443529cad6c81fb487612205 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040IdleInvalidator *MDPComp::idleInvalidator = NULL;
41bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080047int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
radhakrishnac9a67412013-09-25 17:40:42 +053048bool MDPComp::sEnable4k2kYUVSplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800114 char property[PROPERTY_VALUE_MAX];
115
116 sEnabled = false;
117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800120 sEnabled = true;
121 }
122
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700123 sEnableMixedMode = true;
124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
127 sEnableMixedMode = false;
128 }
129
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800130 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
131 if(atoi(property) != 0)
132 sDebugLogs = true;
133 }
134
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800135 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700136 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
137 int val = atoi(property);
138 if(val >= 0)
139 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800140 }
141
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400142 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
143 // Idle invalidation is not necessary on command mode panels
144 long idle_timeout = DEFAULT_IDLE_TIME;
145 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
146 if(atoi(property) != 0)
147 idle_timeout = atoi(property);
148 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800149
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400150 //create Idle Invalidator only when not disabled through property
151 if(idle_timeout != -1)
152 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800153
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400154 if(idleInvalidator == NULL) {
155 ALOGE("%s: failed to instantiate idleInvalidator object",
156 __FUNCTION__);
157 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530158 idleInvalidator->init(timeout_handler, ctx,
159 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800161 }
radhakrishnac9a67412013-09-25 17:40:42 +0530162
Saurabh Shah7c727642014-06-02 15:47:14 -0700163 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
164 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
165 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
166 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
radhakrishnac9a67412013-09-25 17:40:42 +0530167 sEnable4k2kYUVSplit = true;
168 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700169
170 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) &&
171 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) ||
172 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) {
173 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
174 HWC_DISPLAY_PRIMARY);
175 }
176
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700177 return true;
178}
179
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800180void MDPComp::reset(hwc_context_t *ctx) {
181 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700182 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800183 ctx->mOverlay->clear(mDpy);
184 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700185}
186
Raj Kamal4393eaa2014-06-06 13:45:20 +0530187void MDPComp::reset() {
188 sHandleTimeout = false;
189 mModeOn = false;
190}
191
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700192void MDPComp::timeout_handler(void *udata) {
193 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
194
195 if(!ctx) {
196 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
197 return;
198 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800199 Locker::Autolock _l(ctx->mDrawLock);
200 // Handle timeout event only if the previous composition is MDP or MIXED.
201 if(!sHandleTimeout) {
202 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
203 return;
204 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700205 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700206 ALOGE("%s: HWC proc not registered", __FUNCTION__);
207 return;
208 }
209 sIdleFallBack = true;
210 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700211 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212}
213
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800215 hwc_display_contents_1_t* list) {
216 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800217
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800218 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800219 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220 if(!mCurrentFrame.isFBComposed[index]) {
221 layerProp[index].mFlags |= HWC_MDPCOMP;
222 layer->compositionType = HWC_OVERLAY;
223 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800224 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700225 /* Drop the layer when its already present in FB OR when it lies
226 * outside frame's ROI */
227 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800228 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700229 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800230 }
231 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500233
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800234void MDPComp::setRedraw(hwc_context_t *ctx,
235 hwc_display_contents_1_t* list) {
236 mCurrentFrame.needsRedraw = false;
237 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
238 (list->flags & HWC_GEOMETRY_CHANGED) ||
239 isSkipPresent(ctx, mDpy)) {
240 mCurrentFrame.needsRedraw = true;
241 }
242}
243
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800244MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700245 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800246}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800247
Saurabh Shahaa236822013-04-24 18:07:26 -0700248void MDPComp::FrameInfo::reset(const int& numLayers) {
249 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800250 if(mdpToLayer[i].pipeInfo) {
251 delete mdpToLayer[i].pipeInfo;
252 mdpToLayer[i].pipeInfo = NULL;
253 //We dont own the rotator
254 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800255 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800256 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800257
258 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
259 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700260 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800261
Saurabh Shahaa236822013-04-24 18:07:26 -0700262 layerCount = numLayers;
263 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700265 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800266 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800267}
268
Saurabh Shahaa236822013-04-24 18:07:26 -0700269void MDPComp::FrameInfo::map() {
270 // populate layer and MDP maps
271 int mdpIdx = 0;
272 for(int idx = 0; idx < layerCount; idx++) {
273 if(!isFBComposed[idx]) {
274 mdpToLayer[mdpIdx].listIndex = idx;
275 layerToMDP[idx] = mdpIdx++;
276 }
277 }
278}
279
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800280MDPComp::LayerCache::LayerCache() {
281 reset();
282}
283
284void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700285 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530286 memset(&isFBComposed, true, sizeof(isFBComposed));
287 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800288 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700289}
290
291void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530292 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700293 for(int i = 0; i < numAppLayers; i++) {
294 hnd[i] = list->hwLayers[i].handle;
295 }
296}
297
298void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700299 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530300 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
301 memcpy(&drop, &curFrame.drop, sizeof(drop));
302}
303
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800304bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
305 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530306 if(layerCount != curFrame.layerCount)
307 return false;
308 for(int i = 0; i < curFrame.layerCount; i++) {
309 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
310 (curFrame.drop[i] != drop[i])) {
311 return false;
312 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800313 if(curFrame.isFBComposed[i] &&
314 (hnd[i] != list->hwLayers[i].handle)){
315 return false;
316 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530317 }
318 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800319}
320
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700321bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
322 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800323 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700324 (not isValidDimension(ctx,layer))
325 //More conditions here, SKIP, sRGB+Blend etc
326 ) {
327 return false;
328 }
329 return true;
330}
331
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530332bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800333 private_handle_t *hnd = (private_handle_t *)layer->handle;
334
335 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700336 if (layer->flags & HWC_COLOR_FILL) {
337 // Color layer
338 return true;
339 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800340 ALOGE("%s: layer handle is NULL", __FUNCTION__);
341 return false;
342 }
343
Naseer Ahmede850a802013-09-06 13:12:52 -0400344 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400345 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400346 return false;
347
Saurabh Shah62e1d732013-09-17 10:44:05 -0700348 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700349 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700350 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700351 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
352 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700353 int dst_w = dst.right - dst.left;
354 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800355 float w_scale = ((float)crop_w / (float)dst_w);
356 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700357
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800358 /* Workaround for MDP HW limitation in DSI command mode panels where
359 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
360 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530361 * There also is a HW limilation in MDP, minimum block size is 2x2
362 * Fallback to GPU if height is less than 2.
363 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800364 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800365 return false;
366
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800367 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700368 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700369 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800370 const float w_dscale = w_scale;
371 const float h_dscale = h_scale;
372
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800373 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700374
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800375 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700376 /* On targets that doesnt support Decimation (eg.,8x26)
377 * maximum downscale support is overlay pipe downscale.
378 */
379 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
380 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800381 return false;
382 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700383 // Decimation on macrotile format layers is not supported.
384 if(isTileRendered(hnd)) {
385 /* MDP can read maximum MAX_DISPLAY_DIM width.
386 * Bail out if
387 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
388 * 2. exceeds maximum downscale limit
389 */
390 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
391 w_dscale > maxMDPDownscale ||
392 h_dscale > maxMDPDownscale) {
393 return false;
394 }
395 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800396 return false;
397 }
398 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700399 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700400 return false;
401 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700402 }
403
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800404 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
405 const uint32_t upscale =
406 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
407 const float w_uscale = 1.0f / w_scale;
408 const float h_uscale = 1.0f / h_scale;
409
410 if(w_uscale > upscale || h_uscale > upscale)
411 return false;
412 }
413
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800414 return true;
415}
416
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800417bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700418 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800419
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800420 if(!isEnabled()) {
421 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700422 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530423 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530424 qdutils::MDPVersion::getInstance().is8x16() ||
425 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800426 ctx->mVideoTransFlag &&
427 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700428 //1 Padding round to shift pipes across mixers
429 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
430 __FUNCTION__);
431 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800432 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800433 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800434 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700435 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700436 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530437 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
438 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700439 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700440 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700441 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800442}
443
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800444void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
445 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
446 fbRect = getIntersection(fbRect, roi);
447}
448
449/* 1) Identify layers that are not visible or lying outside the updating ROI and
450 * drop them from composition.
451 * 2) If we have a scaling layer which needs cropping against generated
452 * ROI, reset ROI to full resolution. */
453bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
454 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700455 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800456 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800457
458 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800459 if(!isValidRect(visibleRect)) {
460 mCurrentFrame.drop[i] = true;
461 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800462 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800463 }
464
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700465 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700466 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800467 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700469 if(!isValidRect(res)) {
470 mCurrentFrame.drop[i] = true;
471 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800472 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700473 /* Reset frame ROI when any layer which needs scaling also needs ROI
474 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800475 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800476 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700477 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
478 mCurrentFrame.dropCount = 0;
479 return false;
480 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800481
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800482 /* deduct any opaque region from visibleRect */
483 if (layer->blending == HWC_BLENDING_NONE)
484 visibleRect = deductRect(visibleRect, res);
485 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700486 }
487 return true;
488}
489
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800490/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
491 * are updating. If DirtyRegion is applicable, calculate it by accounting all
492 * the changing layer's dirtyRegion. */
493void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
494 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700495 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700497 return;
498
499 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800500 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
501 (int)ctx->dpyAttr[mDpy].yres};
502
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700503 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800504 hwc_layer_1_t* layer = &list->hwLayers[index];
505 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800506 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700507 hwc_rect_t dst = layer->displayFrame;
508 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800510#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800511 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700512 {
513 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
514 int x_off = dst.left - src.left;
515 int y_off = dst.top - src.top;
516 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
517 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800518#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800519
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800520 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700521 }
522 }
523
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800524 /* No layer is updating. Still SF wants a refresh.*/
525 if(!isValidRect(roi))
526 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800527
528 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800529 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800530
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800531 ctx->listStats[mDpy].lRoi = roi;
532 if(!validateAndApplyROI(ctx, list))
533 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534
535 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800536 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
537 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
538}
539
540void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
541 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
542 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
543
544 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
545 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
546 fbRect = getUnion(l_fbRect, r_fbRect);
547}
548/* 1) Identify layers that are not visible or lying outside BOTH the updating
549 * ROI's and drop them from composition. If a layer is spanning across both
550 * the halves of the screen but needed by only ROI, the non-contributing
551 * half will not be programmed for MDP.
552 * 2) If we have a scaling layer which needs cropping against generated
553 * ROI, reset ROI to full resolution. */
554bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
555 hwc_display_contents_1_t* list) {
556
557 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
558
559 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
560 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
561
562 for(int i = numAppLayers - 1; i >= 0; i--){
563 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
564 {
565 mCurrentFrame.drop[i] = true;
566 mCurrentFrame.dropCount++;
567 continue;
568 }
569
570 const hwc_layer_1_t* layer = &list->hwLayers[i];
571 hwc_rect_t dstRect = layer->displayFrame;
572
573 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
574 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
575 hwc_rect_t res = getUnion(l_res, r_res);
576
577 if(!isValidRect(l_res) && !isValidRect(r_res)) {
578 mCurrentFrame.drop[i] = true;
579 mCurrentFrame.dropCount++;
580 } else {
581 /* Reset frame ROI when any layer which needs scaling also needs ROI
582 * cropping */
583 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
584 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
585 mCurrentFrame.dropCount = 0;
586 return false;
587 }
588
589 if (layer->blending == HWC_BLENDING_NONE) {
590 visibleRectL = deductRect(visibleRectL, l_res);
591 visibleRectR = deductRect(visibleRectR, r_res);
592 }
593 }
594 }
595 return true;
596}
597/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
598 * are updating. If DirtyRegion is applicable, calculate it by accounting all
599 * the changing layer's dirtyRegion. */
600void MDPCompSplit::generateROI(hwc_context_t *ctx,
601 hwc_display_contents_1_t* list) {
602 if(!canPartialUpdate(ctx, list))
603 return;
604
605 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
606 int lSplit = getLeftSplit(ctx, mDpy);
607
608 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
609 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
610
611 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
612 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
613
614 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
615 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
616
617 for(int index = 0; index < numAppLayers; index++ ) {
618 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800619 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800620 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800621 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700622 hwc_rect_t dst = layer->displayFrame;
623 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800624
625#ifdef QCOM_BSP
626 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700627 {
628 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
629 int x_off = dst.left - src.left;
630 int y_off = dst.top - src.top;
631 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
632 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800633#endif
634
635 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
636 if(isValidRect(l_dst))
637 l_roi = getUnion(l_roi, l_dst);
638
639 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
640 if(isValidRect(r_dst))
641 r_roi = getUnion(r_roi, r_dst);
642 }
643 }
644
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700645 /* For panels that cannot accept commands in both the interfaces, we cannot
646 * send two ROI's (for each half). We merge them into single ROI and split
647 * them across lSplit for MDP mixer use. The ROI's will be merged again
648 * finally before udpating the panel in the driver. */
649 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
650 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
651 l_roi = getIntersection(temp_roi, l_frame);
652 r_roi = getIntersection(temp_roi, r_frame);
653 }
654
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800655 /* No layer is updating. Still SF wants a refresh. */
656 if(!isValidRect(l_roi) && !isValidRect(r_roi))
657 return;
658
659 l_roi = getSanitizeROI(l_roi, l_frame);
660 r_roi = getSanitizeROI(r_roi, r_frame);
661
662 ctx->listStats[mDpy].lRoi = l_roi;
663 ctx->listStats[mDpy].rRoi = r_roi;
664
665 if(!validateAndApplyROI(ctx, list))
666 resetROI(ctx, mDpy);
667
668 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
669 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
670 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
671 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
672 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
673 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700674}
675
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800676/* Checks for conditions where all the layers marked for MDP comp cannot be
677 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800678bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800679 hwc_display_contents_1_t* list){
680
Saurabh Shahaa236822013-04-24 18:07:26 -0700681 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800682 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800683
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700684 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700685 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
686 return false;
687 }
688
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800689 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700690 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
691 __FUNCTION__,
692 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800693 return false;
694 }
695
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800696 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
697 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
698 // Disable MDP comp on Secondary when the primary is highres panel and
699 // the secondary is a normal 1080p, because, MDP comp on secondary under
700 // in such usecase, decimation gets used for downscale and there will be
701 // a quality mismatch when there will be a fallback to GPU comp
702 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
703 __FUNCTION__);
704 return false;
705 }
706
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800707 // check for action safe flag and downscale mode which requires scaling.
708 if(ctx->dpyAttr[mDpy].mActionSafePresent
709 || ctx->dpyAttr[mDpy].mDownScaleMode) {
710 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
711 return false;
712 }
713
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800714 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800715 hwc_layer_1_t* layer = &list->hwLayers[i];
716 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800717
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800718 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700719 if(!canUseRotator(ctx, mDpy)) {
720 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
721 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700722 return false;
723 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800724 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530725
726 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
727 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700728 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530729 if(qdutils::MDPVersion::getInstance().is8x26() &&
730 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700731 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530732 (!isYuvBuffer(hnd)))
733 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800734 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700735
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700736 if(ctx->mAD->isDoable()) {
737 return false;
738 }
739
Saurabh Shahaa236822013-04-24 18:07:26 -0700740 //If all above hard conditions are met we can do full or partial MDP comp.
741 bool ret = false;
742 if(fullMDPComp(ctx, list)) {
743 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700744 } else if(fullMDPCompWithPTOR(ctx, list)) {
745 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700746 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700747 ret = true;
748 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530749
Saurabh Shahaa236822013-04-24 18:07:26 -0700750 return ret;
751}
752
753bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700754
755 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
756 return false;
757
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700758 //Will benefit presentation / secondary-only layer.
759 if((mDpy > HWC_DISPLAY_PRIMARY) &&
760 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
761 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
762 return false;
763 }
764
765 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
766 for(int i = 0; i < numAppLayers; i++) {
767 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700768 if(not mCurrentFrame.drop[i] and
769 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700770 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
771 return false;
772 }
773 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800774
Saurabh Shahaa236822013-04-24 18:07:26 -0700775 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700776 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
777 sizeof(mCurrentFrame.isFBComposed));
778 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
779 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700780
radhakrishnac9a67412013-09-25 17:40:42 +0530781 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800782 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530783 }
784
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800785 if(!postHeuristicsHandling(ctx, list)) {
786 ALOGD_IF(isDebug(), "post heuristic handling failed");
787 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700788 return false;
789 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700790 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
791 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700792 return true;
793}
794
Sushil Chauhandefd3522014-05-13 18:17:12 -0700795/* Full MDP Composition with Peripheral Tiny Overlap Removal.
796 * MDP bandwidth limitations can be avoided, if the overlap region
797 * covered by the smallest layer at a higher z-order, gets composed
798 * by Copybit on a render buffer, which can be queued to MDP.
799 */
800bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
801 hwc_display_contents_1_t* list) {
802
803 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
804 const int stagesForMDP = min(sMaxPipesPerMixer,
805 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
806
807 // Hard checks where we cannot use this mode
808 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) {
809 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
810 return false;
811 }
812
813 // Frame level checks
814 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
815 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
816 isSecurePresent(ctx, mDpy)) {
817 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
818 return false;
819 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700820 // MDP comp checks
821 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700822 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700823 if(not isSupportedForMDPComp(ctx, layer)) {
824 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
825 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700826 }
827 }
828
Sushil Chauhandefd3522014-05-13 18:17:12 -0700829 /* We cannot use this composition mode, if:
830 1. A below layer needs scaling.
831 2. Overlap is not peripheral to display.
832 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700833 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700834 */
835
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700836 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
837 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
838 memset(overlapRect, 0, sizeof(overlapRect));
839 int layerPixelCount, minPixelCount = 0;
840 int numPTORLayersFound = 0;
841 for (int i = numAppLayers-1; (i >= 0 &&
842 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700843 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700844 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700845 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700846 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
847 // PTOR layer should be peripheral and cannot have transform
848 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
849 has90Transform(layer)) {
850 continue;
851 }
852 if((3 * (layerPixelCount + minPixelCount)) >
853 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
854 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
855 continue;
856 }
857 // Found the PTOR layer
858 bool found = true;
859 for (int j = i-1; j >= 0; j--) {
860 // Check if the layers below this layer qualifies for PTOR comp
861 hwc_layer_1_t* layer = &list->hwLayers[j];
862 hwc_rect_t disFrame = layer->displayFrame;
863 //layer below PTOR is intersecting and has 90 degree transform or
864 // needs scaling cannot be supported.
865 if ((isValidRect(getIntersection(dispFrame, disFrame)))
866 && (has90Transform(layer) || needsScaling(layer))) {
867 found = false;
868 break;
869 }
870 }
871 // Store the minLayer Index
872 if(found) {
873 minLayerIndex[numPTORLayersFound] = i;
874 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
875 minPixelCount += layerPixelCount;
876 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700877 }
878 }
879
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700880 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) {
881 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1",
882 __FUNCTION__);
883 // reset second minLayerIndex[1];
884 minLayerIndex[1] = -1;
885 numPTORLayersFound--;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886 }
887
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700888 // No overlap layers
889 if (!numPTORLayersFound)
890 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700891
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700892 ctx->mPtorInfo.count = numPTORLayersFound;
893 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
894 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
895 }
896
897 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
898 // reset PTOR
899 ctx->mPtorInfo.count = 0;
900 return false;
901 }
902 // Store the displayFrame and the sourceCrops of the layers
903 hwc_rect_t displayFrame[numAppLayers];
904 hwc_rect_t sourceCrop[numAppLayers];
905 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700906 hwc_layer_1_t* layer = &list->hwLayers[i];
907 displayFrame[i] = layer->displayFrame;
908 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700909 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700910
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700911 for(int j = 0; j < numPTORLayersFound; j++) {
912 int index = ctx->mPtorInfo.layerIndex[j];
913 // Remove overlap from crop & displayFrame of below layers
914 for (int i = 0; i < index && index !=-1; i++) {
915 hwc_layer_1_t* layer = &list->hwLayers[i];
916 if(!isValidRect(getIntersection(layer->displayFrame,
917 overlapRect[j]))) {
918 continue;
919 }
920 // Update layer attributes
921 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
922 hwc_rect_t destRect = deductRect(layer->displayFrame,
923 overlapRect[j]);
924 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
925 layer->transform);
926 layer->sourceCropf.left = (float)srcCrop.left;
927 layer->sourceCropf.top = (float)srcCrop.top;
928 layer->sourceCropf.right = (float)srcCrop.right;
929 layer->sourceCropf.bottom = (float)srcCrop.bottom;
930 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700931 }
932
933 mCurrentFrame.mdpCount = numAppLayers;
934 mCurrentFrame.fbCount = 0;
935 mCurrentFrame.fbZ = -1;
936
937 for (int j = 0; j < numAppLayers; j++)
938 mCurrentFrame.isFBComposed[j] = false;
939
940 bool result = postHeuristicsHandling(ctx, list);
941
942 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700943 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700944 hwc_layer_1_t* layer = &list->hwLayers[i];
945 layer->displayFrame = displayFrame[i];
946 layer->sourceCropf.left = (float)sourceCrop[i].left;
947 layer->sourceCropf.top = (float)sourceCrop[i].top;
948 layer->sourceCropf.right = (float)sourceCrop[i].right;
949 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
950 }
951
952 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700953 // reset PTOR
954 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700955 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 } else {
957 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
958 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959 }
960
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700961 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
962 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -0700963 return result;
964}
965
Saurabh Shahaa236822013-04-24 18:07:26 -0700966bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
967{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700968 if(!sEnableMixedMode) {
969 //Mixed mode is disabled. No need to even try caching.
970 return false;
971 }
972
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700973 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800974 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800975 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800976 cacheBasedComp(ctx, list);
977 } else {
978 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800979 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700980 }
981
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700982 return ret;
983}
984
985bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
986 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700987 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
988 return false;
989
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700990 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700991 mCurrentFrame.reset(numAppLayers);
992 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700993
994 //If an MDP marked layer is unsupported cannot do partial MDP Comp
995 for(int i = 0; i < numAppLayers; i++) {
996 if(!mCurrentFrame.isFBComposed[i]) {
997 hwc_layer_1_t* layer = &list->hwLayers[i];
998 if(not isSupportedForMDPComp(ctx, layer)) {
999 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1000 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001001 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001002 return false;
1003 }
1004 }
1005 }
1006
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001007 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301008 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001009 if(!ret) {
1010 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001011 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001012 return false;
1013 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001014
1015 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001016
radhakrishnac9a67412013-09-25 17:40:42 +05301017 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001018 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301019 }
1020
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001021 //Will benefit cases where a video has non-updating background.
1022 if((mDpy > HWC_DISPLAY_PRIMARY) and
1023 (mdpCount > MAX_SEC_LAYERS)) {
1024 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001025 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001026 return false;
1027 }
1028
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001029 if(!postHeuristicsHandling(ctx, list)) {
1030 ALOGD_IF(isDebug(), "post heuristic handling failed");
1031 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001032 return false;
1033 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001034 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1035 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001036
Saurabh Shahaa236822013-04-24 18:07:26 -07001037 return true;
1038}
1039
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001040bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001041 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001042 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1043 return false;
1044
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001045 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001046 return false;
1047 }
1048
Saurabh Shahb772ae32013-11-18 15:40:02 -08001049 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001050 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1051 const int stagesForMDP = min(sMaxPipesPerMixer,
1052 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001053
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001054 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1055 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1056 int lastMDPSupportedIndex = numAppLayers;
1057 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001058
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001059 //Find the minimum MDP batch size
1060 for(int i = 0; i < numAppLayers;i++) {
1061 if(mCurrentFrame.drop[i]) {
1062 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001063 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001064 }
1065 hwc_layer_1_t* layer = &list->hwLayers[i];
1066 if(not isSupportedForMDPComp(ctx, layer)) {
1067 lastMDPSupportedIndex = i;
1068 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1069 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001070 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001071 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001072 }
1073
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001074 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1075 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1076 mCurrentFrame.dropCount);
1077
1078 //Start at a point where the fb batch should at least have 2 layers, for
1079 //this mode to be justified.
1080 while(fbBatchSize < 2) {
1081 ++fbBatchSize;
1082 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001083 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001084
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001085 //If there are no layers for MDP, this mode doesnt make sense.
1086 if(mdpBatchSize < 1) {
1087 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1088 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001089 return false;
1090 }
1091
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001092 mCurrentFrame.reset(numAppLayers);
1093
1094 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1095 while(mdpBatchSize > 0) {
1096 //Mark layers for MDP comp
1097 int mdpBatchLeft = mdpBatchSize;
1098 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1099 if(mCurrentFrame.drop[i]) {
1100 continue;
1101 }
1102 mCurrentFrame.isFBComposed[i] = false;
1103 --mdpBatchLeft;
1104 }
1105
1106 mCurrentFrame.fbZ = mdpBatchSize;
1107 mCurrentFrame.fbCount = fbBatchSize;
1108 mCurrentFrame.mdpCount = mdpBatchSize;
1109
1110 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1111 __FUNCTION__, mdpBatchSize, fbBatchSize,
1112 mCurrentFrame.dropCount);
1113
1114 if(postHeuristicsHandling(ctx, list)) {
1115 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001116 __FUNCTION__);
1117 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1118 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001119 return true;
1120 }
1121
1122 reset(ctx);
1123 --mdpBatchSize;
1124 ++fbBatchSize;
1125 }
1126
1127 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001128}
1129
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001130bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301131 if(mDpy or isSecurePresent(ctx, mDpy) or
1132 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001133 return false;
1134 }
1135 return true;
1136}
1137
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001138bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1139 hwc_display_contents_1_t* list){
1140 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1141 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1142 mDpy ) {
1143 return false;
1144 }
1145 return true;
1146}
1147
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001148bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1149 hwc_display_contents_1_t* list) {
1150 const bool secureOnly = true;
1151 return videoOnlyComp(ctx, list, not secureOnly) or
1152 videoOnlyComp(ctx, list, secureOnly);
1153}
1154
1155bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001156 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001157 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1158 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001159 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001160
Saurabh Shahaa236822013-04-24 18:07:26 -07001161 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001162 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001163 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001164 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001165
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001166 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1167 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001168 return false;
1169 }
1170
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001171 /* Bail out if we are processing only secured video layers
1172 * and we dont have any */
1173 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001174 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001175 return false;
1176 }
1177
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001178 if(mCurrentFrame.fbCount)
1179 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001180
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001181 if(sEnable4k2kYUVSplit){
1182 adjustForSourceSplit(ctx, list);
1183 }
1184
1185 if(!postHeuristicsHandling(ctx, list)) {
1186 ALOGD_IF(isDebug(), "post heuristic handling failed");
1187 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001188 return false;
1189 }
1190
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001191 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1192 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001193 return true;
1194}
1195
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001196/* Checks for conditions where YUV layers cannot be bypassed */
1197bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001198 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001199 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001200 return false;
1201 }
1202
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001203 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001204 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1205 return false;
1206 }
1207
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001208 if(isSecuring(ctx, layer)) {
1209 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1210 return false;
1211 }
1212
Saurabh Shah4fdde762013-04-30 18:47:33 -07001213 if(!isValidDimension(ctx, layer)) {
1214 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1215 __FUNCTION__);
1216 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001217 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001218
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001219 if(layer->planeAlpha < 0xFF) {
1220 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1221 in video only mode",
1222 __FUNCTION__);
1223 return false;
1224 }
1225
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001226 return true;
1227}
1228
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301229/* starts at fromIndex and check for each layer to find
1230 * if it it has overlapping with any Updating layer above it in zorder
1231 * till the end of the batch. returns true if it finds any intersection */
1232bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1233 int fromIndex, int toIndex) {
1234 for(int i = fromIndex; i < toIndex; i++) {
1235 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1236 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1237 return false;
1238 }
1239 }
1240 }
1241 return true;
1242}
1243
1244/* Checks if given layer at targetLayerIndex has any
1245 * intersection with all the updating layers in beween
1246 * fromIndex and toIndex. Returns true if it finds intersectiion */
1247bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1248 int fromIndex, int toIndex, int targetLayerIndex) {
1249 for(int i = fromIndex; i <= toIndex; i++) {
1250 if(!mCurrentFrame.isFBComposed[i]) {
1251 if(areLayersIntersecting(&list->hwLayers[i],
1252 &list->hwLayers[targetLayerIndex])) {
1253 return true;
1254 }
1255 }
1256 }
1257 return false;
1258}
1259
1260int MDPComp::getBatch(hwc_display_contents_1_t* list,
1261 int& maxBatchStart, int& maxBatchEnd,
1262 int& maxBatchCount) {
1263 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301264 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001265 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301266 while (i < mCurrentFrame.layerCount) {
1267 int batchCount = 0;
1268 int batchStart = i;
1269 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001270 /* Adjust batch Z order with the dropped layers so far */
1271 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301272 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301273 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301274 while(i < mCurrentFrame.layerCount) {
1275 if(!mCurrentFrame.isFBComposed[i]) {
1276 if(!batchCount) {
1277 i++;
1278 break;
1279 }
1280 updatingLayersAbove++;
1281 i++;
1282 continue;
1283 } else {
1284 if(mCurrentFrame.drop[i]) {
1285 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001286 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301287 continue;
1288 } else if(updatingLayersAbove <= 0) {
1289 batchCount++;
1290 batchEnd = i;
1291 i++;
1292 continue;
1293 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1294
1295 // We have a valid updating layer already. If layer-i not
1296 // have overlapping with all updating layers in between
1297 // batch-start and i, then we can add layer i to batch.
1298 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1299 batchCount++;
1300 batchEnd = i;
1301 i++;
1302 continue;
1303 } else if(canPushBatchToTop(list, batchStart, i)) {
1304 //If All the non-updating layers with in this batch
1305 //does not have intersection with the updating layers
1306 //above in z-order, then we can safely move the batch to
1307 //higher z-order. Increment fbZ as it is moving up.
1308 if( firstZReverseIndex < 0) {
1309 firstZReverseIndex = i;
1310 }
1311 batchCount++;
1312 batchEnd = i;
1313 fbZ += updatingLayersAbove;
1314 i++;
1315 updatingLayersAbove = 0;
1316 continue;
1317 } else {
1318 //both failed.start the loop again from here.
1319 if(firstZReverseIndex >= 0) {
1320 i = firstZReverseIndex;
1321 }
1322 break;
1323 }
1324 }
1325 }
1326 }
1327 if(batchCount > maxBatchCount) {
1328 maxBatchCount = batchCount;
1329 maxBatchStart = batchStart;
1330 maxBatchEnd = batchEnd;
1331 fbZOrder = fbZ;
1332 }
1333 }
1334 return fbZOrder;
1335}
1336
1337bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1338 hwc_display_contents_1_t* list) {
1339 /* Idea is to keep as many non-updating(cached) layers in FB and
1340 * send rest of them through MDP. This is done in 2 steps.
1341 * 1. Find the maximum contiguous batch of non-updating layers.
1342 * 2. See if we can improve this batch size for caching by adding
1343 * opaque layers around the batch, if they don't have
1344 * any overlapping with the updating layers in between.
1345 * NEVER mark an updating layer for caching.
1346 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001347
1348 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001349 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001350 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301351 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001352
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001353 /* Nothing is cached. No batching needed */
1354 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001355 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001356 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001357
1358 /* No MDP comp layers, try to use other comp modes */
1359 if(mCurrentFrame.mdpCount == 0) {
1360 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001361 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001362
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301363 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001364
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301365 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001366 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001367 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001368 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301369 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001370 if(!mCurrentFrame.drop[i]){
1371 //If an unsupported layer is being attempted to
1372 //be pulled out we should fail
1373 if(not isSupportedForMDPComp(ctx, layer)) {
1374 return false;
1375 }
1376 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001377 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001378 }
1379 }
1380
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301381 // update the frame data
1382 mCurrentFrame.fbZ = fbZ;
1383 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001384 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001385 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001386
1387 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301388 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001389
1390 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001391}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001392
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001393void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001394 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001395 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001396 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001397
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001398 for(int i = 0; i < numAppLayers; i++) {
1399 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001400 if(!mCurrentFrame.drop[i])
1401 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001402 mCurrentFrame.isFBComposed[i] = true;
1403 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001404 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001405 }
1406 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001407
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001408 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001409 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1410 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001411
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001412 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1413 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1414 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001415}
1416
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001417void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1418 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001419 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1420 for(int index = 0;index < nYuvCount; index++){
1421 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1422 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1423
1424 if(!isYUVDoable(ctx, layer)) {
1425 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1426 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1427 mCurrentFrame.fbCount++;
1428 }
1429 } else {
1430 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001431 private_handle_t *hnd = (private_handle_t *)layer->handle;
1432 if(!secureOnly || isSecureBuffer(hnd)) {
1433 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1434 mCurrentFrame.fbCount--;
1435 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001436 }
1437 }
1438 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001439
1440 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001441 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1442 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001443 mCurrentFrame.fbCount);
1444}
1445
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001446hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1447 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001448 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001449
1450 /* Update only the region of FB needed for composition */
1451 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1452 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1453 hwc_layer_1_t* layer = &list->hwLayers[i];
1454 hwc_rect_t dst = layer->displayFrame;
1455 fbRect = getUnion(fbRect, dst);
1456 }
1457 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001458 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001459 return fbRect;
1460}
1461
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001462bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1463 hwc_display_contents_1_t* list) {
1464
1465 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001466 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001467 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1468 return false;
1469 }
1470
1471 //Limitations checks
1472 if(!hwLimitationsCheck(ctx, list)) {
1473 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1474 return false;
1475 }
1476
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001477 //Configure framebuffer first if applicable
1478 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001479 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001480 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1481 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001482 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1483 __FUNCTION__);
1484 return false;
1485 }
1486 }
1487
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001488 mCurrentFrame.map();
1489
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001490 if(!allocLayerPipes(ctx, list)) {
1491 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001492 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001493 }
1494
1495 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001496 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001497 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001498 int mdpIndex = mCurrentFrame.layerToMDP[index];
1499 hwc_layer_1_t* layer = &list->hwLayers[index];
1500
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301501 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1502 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1503 mdpNextZOrder++;
1504 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001505 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1506 cur_pipe->zOrder = mdpNextZOrder++;
1507
radhakrishnac9a67412013-09-25 17:40:42 +05301508 private_handle_t *hnd = (private_handle_t *)layer->handle;
1509 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1510 if(configure4k2kYuv(ctx, layer,
1511 mCurrentFrame.mdpToLayer[mdpIndex])
1512 != 0 ){
1513 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1514 for layer %d",__FUNCTION__, index);
1515 return false;
1516 }
1517 else{
1518 mdpNextZOrder++;
1519 }
1520 continue;
1521 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001522 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1523 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301524 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001525 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001526 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001527 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001528 }
1529
Saurabh Shaha36be922013-12-16 18:18:39 -08001530 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1531 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1532 ,__FUNCTION__, mDpy);
1533 return false;
1534 }
1535
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001536 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001537 return true;
1538}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001539
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001540bool MDPComp::resourceCheck(hwc_context_t* ctx,
1541 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001542 const bool fbUsed = mCurrentFrame.fbCount;
1543 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1544 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1545 return false;
1546 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001547 // Init rotCount to number of rotate sessions used by other displays
1548 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1549 // Count the number of rotator sessions required for current display
1550 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1551 if(!mCurrentFrame.isFBComposed[index]) {
1552 hwc_layer_1_t* layer = &list->hwLayers[index];
1553 private_handle_t *hnd = (private_handle_t *)layer->handle;
1554 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1555 rotCount++;
1556 }
1557 }
1558 }
1559 // if number of layers to rotate exceeds max rotator sessions, bail out.
1560 if(rotCount > RotMgr::MAX_ROT_SESS) {
1561 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1562 __FUNCTION__, mDpy);
1563 return false;
1564 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001565 return true;
1566}
1567
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301568bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1569 hwc_display_contents_1_t* list) {
1570
1571 //A-family hw limitation:
1572 //If a layer need alpha scaling, MDP can not support.
1573 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1574 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1575 if(!mCurrentFrame.isFBComposed[i] &&
1576 isAlphaScaled( &list->hwLayers[i])) {
1577 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1578 return false;
1579 }
1580 }
1581 }
1582
1583 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1584 //If multiple layers requires downscaling and also they are overlapping
1585 //fall back to GPU since MDSS can not handle it.
1586 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1587 qdutils::MDPVersion::getInstance().is8x26()) {
1588 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1589 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1590 if(!mCurrentFrame.isFBComposed[i] &&
1591 isDownscaleRequired(botLayer)) {
1592 //if layer-i is marked for MDP and needs downscaling
1593 //check if any MDP layer on top of i & overlaps with layer-i
1594 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1595 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1596 if(!mCurrentFrame.isFBComposed[j] &&
1597 isDownscaleRequired(topLayer)) {
1598 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1599 topLayer->displayFrame);
1600 if(isValidRect(r))
1601 return false;
1602 }
1603 }
1604 }
1605 }
1606 }
1607 return true;
1608}
1609
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001611 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001612 char property[PROPERTY_VALUE_MAX];
1613
Raj Kamal4393eaa2014-06-06 13:45:20 +05301614 if(!ctx || !list) {
1615 ALOGE("%s: Invalid context or list",__FUNCTION__);
1616 mCachedFrame.reset();
1617 return -1;
1618 }
1619
1620 const int numLayers = ctx->listStats[mDpy].numAppLayers;
1621
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001622 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1623 int currentFlags = atoi(property);
1624 if(currentFlags != sSimulationFlags) {
1625 sSimulationFlags = currentFlags;
1626 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1627 sSimulationFlags, sSimulationFlags);
1628 }
1629 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001630 // reset PTOR
1631 if(!mDpy)
1632 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001633
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301634 //Do not cache the information for next draw cycle.
1635 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1636 ALOGI("%s: Unsupported layer count for mdp composition",
1637 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001638 mCachedFrame.reset();
1639 return -1;
1640 }
1641
Saurabh Shahb39f8152013-08-22 10:21:44 -07001642 //reset old data
1643 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001644 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1645 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301646
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001647 // Detect the start of animation and fall back to GPU only once to cache
1648 // all the layers in FB and display FB content untill animation completes.
1649 if(ctx->listStats[mDpy].isDisplayAnimating) {
1650 mCurrentFrame.needsRedraw = false;
1651 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1652 mCurrentFrame.needsRedraw = true;
1653 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1654 }
1655 setMDPCompLayerFlags(ctx, list);
1656 mCachedFrame.updateCounts(mCurrentFrame);
1657 ret = -1;
1658 return ret;
1659 } else {
1660 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1661 }
1662
Saurabh Shahb39f8152013-08-22 10:21:44 -07001663 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001664 if(isFrameDoable(ctx)) {
1665 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001666
Raj Kamal4393eaa2014-06-06 13:45:20 +05301667 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list);
1668 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001669 setMDPCompLayerFlags(ctx, list);
1670 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001671 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001672 reset(ctx);
1673 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1674 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001675 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001676 }
1677 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001678 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1679 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001680 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001681 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001682
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001683 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001684 ALOGD("GEOMETRY change: %d",
1685 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001687 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001688 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001689 }
1690
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001691 mCachedFrame.cacheAll(list);
1692 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001693 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001694}
1695
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001696bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301697
1698 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301699 int mdpIndex = mCurrentFrame.layerToMDP[index];
1700 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1701 info.pipeInfo = new MdpYUVPipeInfo;
1702 info.rot = NULL;
1703 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301704
1705 pipe_info.lIndex = ovutils::OV_INVALID;
1706 pipe_info.rIndex = ovutils::OV_INVALID;
1707
Saurabh Shahc62f3982014-03-05 14:28:26 -08001708 Overlay::PipeSpecs pipeSpecs;
1709 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1710 pipeSpecs.needsScaling = true;
1711 pipeSpecs.dpy = mDpy;
1712 pipeSpecs.fb = false;
1713
1714 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301715 if(pipe_info.lIndex == ovutils::OV_INVALID){
1716 bRet = false;
1717 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1718 __FUNCTION__);
1719 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001720 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301721 if(pipe_info.rIndex == ovutils::OV_INVALID){
1722 bRet = false;
1723 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1724 __FUNCTION__);
1725 }
1726 return bRet;
1727}
Sushil Chauhandefd3522014-05-13 18:17:12 -07001728
1729int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1730 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001731 if (ctx->mPtorInfo.isActive()) {
1732 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001733 if (fd < 0) {
1734 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001735 }
1736 }
1737 return fd;
1738}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001739//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001740
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001741void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301742 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001743 //If 4k2k Yuv layer split is possible, and if
1744 //fbz is above 4k2k layer, increment fb zorder by 1
1745 //as we split 4k2k layer and increment zorder for right half
1746 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07001747 if(!ctx)
1748 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001749 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301750 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1751 index++) {
1752 if(!mCurrentFrame.isFBComposed[index]) {
1753 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1754 mdpNextZOrder++;
1755 }
1756 mdpNextZOrder++;
1757 hwc_layer_1_t* layer = &list->hwLayers[index];
1758 private_handle_t *hnd = (private_handle_t *)layer->handle;
1759 if(is4kx2kYuvBuffer(hnd)) {
1760 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1761 mCurrentFrame.fbZ += 1;
1762 mdpNextZOrder++;
1763 //As we split 4kx2k yuv layer and program to 2 VG pipes
1764 //(if available) increase mdpcount by 1.
1765 mCurrentFrame.mdpCount++;
1766 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001767 }
1768 }
1769 }
radhakrishnac9a67412013-09-25 17:40:42 +05301770}
1771
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001772/*
1773 * Configures pipe(s) for MDP composition
1774 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001775int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001776 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001777 MdpPipeInfoNonSplit& mdp_info =
1778 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001779 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1780 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1781 eIsFg isFg = IS_FG_OFF;
1782 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001783
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1785 __FUNCTION__, layer, zOrder, dest);
1786
Saurabh Shah88e4d272013-09-03 13:31:29 -07001787 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001789}
1790
Saurabh Shah88e4d272013-09-03 13:31:29 -07001791bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001792 hwc_display_contents_1_t* list) {
1793 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001794
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001795 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001796
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001797 hwc_layer_1_t* layer = &list->hwLayers[index];
1798 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301799 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001800 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301801 continue;
1802 }
1803 }
1804
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001805 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001806 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001807 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001808 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001809 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001810
Saurabh Shahc62f3982014-03-05 14:28:26 -08001811 Overlay::PipeSpecs pipeSpecs;
1812 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1813 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1814 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1815 (qdutils::MDPVersion::getInstance().is8x26() and
1816 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1817 pipeSpecs.dpy = mDpy;
1818 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08001819 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001820
Saurabh Shahc62f3982014-03-05 14:28:26 -08001821 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1822
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001823 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001824 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001825 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001826 }
1827 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001828 return true;
1829}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001830
radhakrishnac9a67412013-09-25 17:40:42 +05301831int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1832 PipeLayerPair& PipeLayerPair) {
1833 MdpYUVPipeInfo& mdp_info =
1834 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1835 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1836 eIsFg isFg = IS_FG_OFF;
1837 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1838 eDest lDest = mdp_info.lIndex;
1839 eDest rDest = mdp_info.rIndex;
1840
1841 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1842 lDest, rDest, &PipeLayerPair.rot);
1843}
1844
Saurabh Shah88e4d272013-09-03 13:31:29 -07001845bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001846
Raj Kamal4393eaa2014-06-06 13:45:20 +05301847 if(!isEnabled() or !mModeOn) {
1848 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301849 return true;
1850 }
1851
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001852 // Set the Handle timeout to true for MDP or MIXED composition.
1853 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1854 sHandleTimeout = true;
1855 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001856
1857 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001858 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001859
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001860 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1861 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001862 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001863 if(mCurrentFrame.isFBComposed[i]) continue;
1864
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001865 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001866 private_handle_t *hnd = (private_handle_t *)layer->handle;
1867 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001868 if (!(layer->flags & HWC_COLOR_FILL)) {
1869 ALOGE("%s handle null", __FUNCTION__);
1870 return false;
1871 }
1872 // No PLAY for Color layer
1873 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1874 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001875 }
1876
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001877 int mdpIndex = mCurrentFrame.layerToMDP[i];
1878
radhakrishnac9a67412013-09-25 17:40:42 +05301879 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1880 {
1881 MdpYUVPipeInfo& pipe_info =
1882 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1883 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1884 ovutils::eDest indexL = pipe_info.lIndex;
1885 ovutils::eDest indexR = pipe_info.rIndex;
1886 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301887 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301888 if(rot) {
1889 rot->queueBuffer(fd, offset);
1890 fd = rot->getDstMemId();
1891 offset = rot->getDstOffset();
1892 }
1893 if(indexL != ovutils::OV_INVALID) {
1894 ovutils::eDest destL = (ovutils::eDest)indexL;
1895 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1896 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1897 if (!ov.queueBuffer(fd, offset, destL)) {
1898 ALOGE("%s: queueBuffer failed for display:%d",
1899 __FUNCTION__, mDpy);
1900 return false;
1901 }
1902 }
1903
1904 if(indexR != ovutils::OV_INVALID) {
1905 ovutils::eDest destR = (ovutils::eDest)indexR;
1906 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1907 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1908 if (!ov.queueBuffer(fd, offset, destR)) {
1909 ALOGE("%s: queueBuffer failed for display:%d",
1910 __FUNCTION__, mDpy);
1911 return false;
1912 }
1913 }
1914 }
1915 else{
1916 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001917 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301918 ovutils::eDest dest = pipe_info.index;
1919 if(dest == ovutils::OV_INVALID) {
1920 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001921 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301922 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001923
radhakrishnac9a67412013-09-25 17:40:42 +05301924 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1925 continue;
1926 }
1927
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001928 int fd = hnd->fd;
1929 uint32_t offset = (uint32_t)hnd->offset;
1930 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
1931 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001932 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001933 fd = hnd->fd;
1934 // Use the offset of the RenderBuffer
1935 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
Sushil Chauhandefd3522014-05-13 18:17:12 -07001936 }
1937
radhakrishnac9a67412013-09-25 17:40:42 +05301938 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1939 using pipe: %d", __FUNCTION__, layer,
1940 hnd, dest );
1941
radhakrishnac9a67412013-09-25 17:40:42 +05301942 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1943 if(rot) {
1944 if(!rot->queueBuffer(fd, offset))
1945 return false;
1946 fd = rot->getDstMemId();
1947 offset = rot->getDstOffset();
1948 }
1949
1950 if (!ov.queueBuffer(fd, offset, dest)) {
1951 ALOGE("%s: queueBuffer failed for display:%d ",
1952 __FUNCTION__, mDpy);
1953 return false;
1954 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001955 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001956
1957 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001958 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001959 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001960}
1961
Saurabh Shah88e4d272013-09-03 13:31:29 -07001962//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001963
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001964void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301965 hwc_display_contents_1_t* list){
1966 //if 4kx2k yuv layer is totally present in either in left half
1967 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05301968 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05301969 if(mCurrentFrame.fbZ >= 0) {
1970 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1971 index++) {
1972 if(!mCurrentFrame.isFBComposed[index]) {
1973 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1974 mdpNextZOrder++;
1975 }
1976 mdpNextZOrder++;
1977 hwc_layer_1_t* layer = &list->hwLayers[index];
1978 private_handle_t *hnd = (private_handle_t *)layer->handle;
1979 if(is4kx2kYuvBuffer(hnd)) {
1980 hwc_rect_t dst = layer->displayFrame;
1981 if((dst.left > lSplit) || (dst.right < lSplit)) {
1982 mCurrentFrame.mdpCount += 1;
1983 }
1984 if(mdpNextZOrder <= mCurrentFrame.fbZ)
1985 mCurrentFrame.fbZ += 1;
1986 mdpNextZOrder++;
1987 }
1988 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001989 }
radhakrishnac9a67412013-09-25 17:40:42 +05301990 }
1991}
1992
Saurabh Shah88e4d272013-09-03 13:31:29 -07001993bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001994 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001995
Saurabh Shahc62f3982014-03-05 14:28:26 -08001996 const int lSplit = getLeftSplit(ctx, mDpy);
1997 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001998 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001999 pipe_info.lIndex = ovutils::OV_INVALID;
2000 pipe_info.rIndex = ovutils::OV_INVALID;
2001
Saurabh Shahc62f3982014-03-05 14:28:26 -08002002 Overlay::PipeSpecs pipeSpecs;
2003 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2004 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2005 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2006 pipeSpecs.dpy = mDpy;
2007 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2008 pipeSpecs.fb = false;
2009
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002010 // Acquire pipe only for the updating half
2011 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2012 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2013
2014 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002015 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002016 if(pipe_info.lIndex == ovutils::OV_INVALID)
2017 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002018 }
2019
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002020 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002021 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2022 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002023 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002024 return false;
2025 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002026
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002027 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002028}
2029
Saurabh Shah88e4d272013-09-03 13:31:29 -07002030bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002031 hwc_display_contents_1_t* list) {
2032 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002033
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002034 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002035
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002036 hwc_layer_1_t* layer = &list->hwLayers[index];
2037 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302038 hwc_rect_t dst = layer->displayFrame;
2039 const int lSplit = getLeftSplit(ctx, mDpy);
2040 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
2041 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002042 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302043 continue;
2044 }
2045 }
2046 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002047 int mdpIndex = mCurrentFrame.layerToMDP[index];
2048 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002049 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002050 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002051 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002052
Saurabh Shahc62f3982014-03-05 14:28:26 -08002053 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2054 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2055 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002056 return false;
2057 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002058 }
2059 return true;
2060}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002061
radhakrishnac9a67412013-09-25 17:40:42 +05302062int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2063 PipeLayerPair& PipeLayerPair) {
2064 const int lSplit = getLeftSplit(ctx, mDpy);
2065 hwc_rect_t dst = layer->displayFrame;
2066 if((dst.left > lSplit)||(dst.right < lSplit)){
2067 MdpYUVPipeInfo& mdp_info =
2068 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2069 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2070 eIsFg isFg = IS_FG_OFF;
2071 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2072 eDest lDest = mdp_info.lIndex;
2073 eDest rDest = mdp_info.rIndex;
2074
2075 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
2076 lDest, rDest, &PipeLayerPair.rot);
2077 }
2078 else{
2079 return configure(ctx, layer, PipeLayerPair);
2080 }
2081}
2082
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002083/*
2084 * Configures pipe(s) for MDP composition
2085 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002086int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002087 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002088 MdpPipeInfoSplit& mdp_info =
2089 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002090 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2091 eIsFg isFg = IS_FG_OFF;
2092 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
2093 eDest lDest = mdp_info.lIndex;
2094 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002095
2096 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2097 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2098
Saurabh Shah88e4d272013-09-03 13:31:29 -07002099 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002100 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002101}
2102
Saurabh Shah88e4d272013-09-03 13:31:29 -07002103bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002104
Raj Kamal4393eaa2014-06-06 13:45:20 +05302105 if(!isEnabled() or !mModeOn) {
2106 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302107 return true;
2108 }
2109
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002110 // Set the Handle timeout to true for MDP or MIXED composition.
2111 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2112 sHandleTimeout = true;
2113 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002114
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002115 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002116 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002117
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002118 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2119 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002120 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002121 if(mCurrentFrame.isFBComposed[i]) continue;
2122
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002123 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002124 private_handle_t *hnd = (private_handle_t *)layer->handle;
2125 if(!hnd) {
2126 ALOGE("%s handle null", __FUNCTION__);
2127 return false;
2128 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002129
2130 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2131 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002132 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002133
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002134 int mdpIndex = mCurrentFrame.layerToMDP[i];
2135
radhakrishnac9a67412013-09-25 17:40:42 +05302136 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
2137 {
2138 MdpYUVPipeInfo& pipe_info =
2139 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2140 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2141 ovutils::eDest indexL = pipe_info.lIndex;
2142 ovutils::eDest indexR = pipe_info.rIndex;
2143 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302144 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302145 if(rot) {
2146 rot->queueBuffer(fd, offset);
2147 fd = rot->getDstMemId();
2148 offset = rot->getDstOffset();
2149 }
2150 if(indexL != ovutils::OV_INVALID) {
2151 ovutils::eDest destL = (ovutils::eDest)indexL;
2152 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2153 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2154 if (!ov.queueBuffer(fd, offset, destL)) {
2155 ALOGE("%s: queueBuffer failed for display:%d",
2156 __FUNCTION__, mDpy);
2157 return false;
2158 }
2159 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002160
radhakrishnac9a67412013-09-25 17:40:42 +05302161 if(indexR != ovutils::OV_INVALID) {
2162 ovutils::eDest destR = (ovutils::eDest)indexR;
2163 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2164 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2165 if (!ov.queueBuffer(fd, offset, destR)) {
2166 ALOGE("%s: queueBuffer failed for display:%d",
2167 __FUNCTION__, mDpy);
2168 return false;
2169 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002170 }
2171 }
radhakrishnac9a67412013-09-25 17:40:42 +05302172 else{
2173 MdpPipeInfoSplit& pipe_info =
2174 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2175 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002176
radhakrishnac9a67412013-09-25 17:40:42 +05302177 ovutils::eDest indexL = pipe_info.lIndex;
2178 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002179
radhakrishnac9a67412013-09-25 17:40:42 +05302180 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002181 uint32_t offset = (uint32_t)hnd->offset;
2182 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2183 if (!mDpy && (index != -1)) {
2184 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2185 fd = hnd->fd;
2186 offset = ctx->mPtorInfo.mRenderBuffOffset[index];
2187 }
radhakrishnac9a67412013-09-25 17:40:42 +05302188
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002189 if(ctx->mAD->draw(ctx, fd, offset)) {
2190 fd = ctx->mAD->getDstFd();
2191 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002192 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002193
radhakrishnac9a67412013-09-25 17:40:42 +05302194 if(rot) {
2195 rot->queueBuffer(fd, offset);
2196 fd = rot->getDstMemId();
2197 offset = rot->getDstOffset();
2198 }
2199
2200 //************* play left mixer **********
2201 if(indexL != ovutils::OV_INVALID) {
2202 ovutils::eDest destL = (ovutils::eDest)indexL;
2203 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2204 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2205 if (!ov.queueBuffer(fd, offset, destL)) {
2206 ALOGE("%s: queueBuffer failed for left mixer",
2207 __FUNCTION__);
2208 return false;
2209 }
2210 }
2211
2212 //************* play right mixer **********
2213 if(indexR != ovutils::OV_INVALID) {
2214 ovutils::eDest destR = (ovutils::eDest)indexR;
2215 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2216 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2217 if (!ov.queueBuffer(fd, offset, destR)) {
2218 ALOGE("%s: queueBuffer failed for right mixer",
2219 __FUNCTION__);
2220 return false;
2221 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002222 }
2223 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002224
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002225 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2226 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002227
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002228 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002229}
Saurabh Shahab47c692014-02-12 18:45:57 -08002230
2231//================MDPCompSrcSplit==============================================
2232bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002233 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002234 private_handle_t *hnd = (private_handle_t *)layer->handle;
2235 hwc_rect_t dst = layer->displayFrame;
2236 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2237 pipe_info.lIndex = ovutils::OV_INVALID;
2238 pipe_info.rIndex = ovutils::OV_INVALID;
2239
2240 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2241 //should have a higher priority than the right one. Pipe priorities are
2242 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002243
Saurabh Shahc62f3982014-03-05 14:28:26 -08002244 Overlay::PipeSpecs pipeSpecs;
2245 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2246 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2247 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2248 pipeSpecs.dpy = mDpy;
2249 pipeSpecs.fb = false;
2250
Saurabh Shahab47c692014-02-12 18:45:57 -08002251 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002252 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002253 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002254 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002255 }
2256
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002257 /* Use 2 pipes IF
2258 a) Layer's crop width is > 2048 or
2259 b) Layer's dest width > 2048 or
2260 c) On primary, driver has indicated with caps to split always. This is
2261 based on an empirically derived value of panel height. Applied only
2262 if the layer's width is > mixer's width
2263 */
2264
2265 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2266 qdutils::MDPVersion::getInstance().isSrcSplitAlways();
2267 int lSplit = getLeftSplit(ctx, mDpy);
2268 int dstWidth = dst.right - dst.left;
2269 int cropWidth = crop.right - crop.left;
2270
2271 if(dstWidth > qdutils::MAX_DISPLAY_DIM or
2272 cropWidth > qdutils::MAX_DISPLAY_DIM or
2273 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002274 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002275 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002276 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002277 }
2278
2279 // Return values
2280 // 1 Left pipe is higher priority, do nothing.
2281 // 0 Pipes of same priority.
2282 //-1 Right pipe is of higher priority, needs swap.
2283 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2284 pipe_info.rIndex) == -1) {
2285 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002286 }
2287 }
2288
2289 return true;
2290}
2291
Saurabh Shahab47c692014-02-12 18:45:57 -08002292int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2293 PipeLayerPair& PipeLayerPair) {
2294 private_handle_t *hnd = (private_handle_t *)layer->handle;
2295 if(!hnd) {
2296 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2297 return -1;
2298 }
2299 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2300 MdpPipeInfoSplit& mdp_info =
2301 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2302 Rotator **rot = &PipeLayerPair.rot;
2303 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2304 eIsFg isFg = IS_FG_OFF;
2305 eDest lDest = mdp_info.lIndex;
2306 eDest rDest = mdp_info.rIndex;
2307 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2308 hwc_rect_t dst = layer->displayFrame;
2309 int transform = layer->transform;
2310 eTransform orient = static_cast<eTransform>(transform);
2311 const int downscale = 0;
2312 int rotFlags = ROT_FLAGS_NONE;
2313 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2314 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2315
2316 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2317 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2318
2319 // Handle R/B swap
2320 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2321 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2322 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2323 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2324 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2325 }
2326
Saurabh Shah97e2d802014-04-14 18:03:54 -07002327 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002328 setMdpFlags(ctx, layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002329
2330 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2331 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002332 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002333 }
2334
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08002335 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002336 (*rot) = ctx->mRotMgr->getNext();
2337 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002338 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002339 //If the video is using a single pipe, enable BWC
2340 if(rDest == OV_INVALID) {
2341 BwcPM::setBwc(crop, dst, transform, mdpFlags);
2342 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002343 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002344 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002345 ALOGE("%s: configRotator failed!", __FUNCTION__);
2346 return -1;
2347 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002348 updateSource(orient, whf, crop, *rot);
Saurabh Shahab47c692014-02-12 18:45:57 -08002349 rotFlags |= ROT_PREROTATED;
2350 }
2351
2352 //If 2 pipes being used, divide layer into half, crop and dst
2353 hwc_rect_t cropL = crop;
2354 hwc_rect_t cropR = crop;
2355 hwc_rect_t dstL = dst;
2356 hwc_rect_t dstR = dst;
2357 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2358 cropL.right = (crop.right + crop.left) / 2;
2359 cropR.left = cropL.right;
2360 sanitizeSourceCrop(cropL, cropR, hnd);
2361
2362 //Swap crops on H flip since 2 pipes are being used
2363 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2364 hwc_rect_t tmp = cropL;
2365 cropL = cropR;
2366 cropR = tmp;
2367 }
2368
2369 dstL.right = (dst.right + dst.left) / 2;
2370 dstR.left = dstL.right;
2371 }
2372
2373 //For the mdp, since either we are pre-rotating or MDP does flips
2374 orient = OVERLAY_TRANSFORM_0;
2375 transform = 0;
2376
2377 //configure left pipe
2378 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002379 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002380 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2381 (ovutils::eBlending) getBlending(layer->blending));
2382
2383 if(configMdp(ctx->mOverlay, pargL, orient,
2384 cropL, dstL, metadata, lDest) < 0) {
2385 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2386 return -1;
2387 }
2388 }
2389
2390 //configure right pipe
2391 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07002392 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08002393 static_cast<eRotFlags>(rotFlags),
2394 layer->planeAlpha,
2395 (ovutils::eBlending) getBlending(layer->blending));
2396 if(configMdp(ctx->mOverlay, pargR, orient,
2397 cropR, dstR, metadata, rDest) < 0) {
2398 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2399 return -1;
2400 }
2401 }
2402
2403 return 0;
2404}
2405
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002406}; //namespace
2407