blob: 4e7d101a4b6663252de2aafa52a8f7e45eab7b83 [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>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070022#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080029
Saurabh Shah85234ec2013-04-12 17:09:00 -070030using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070031using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080032using namespace overlay::utils;
33namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035namespace qhwc {
36
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080037//==============MDPComp========================================================
38
Saurabh Shah59562ff2014-09-30 16:13:12 -070039IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080041bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050043bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070044bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070045int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070046int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080049int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053050bool MDPComp::enablePartialUpdateForMDP3 = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070051MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070052 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
53 sSrcSplitEnabled = true;
54 return new MDPCompSrcSplit(dpy);
55 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070056 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080057 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070058 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080059}
60
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080061MDPComp::MDPComp(int dpy):mDpy(dpy){};
62
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070063void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080064{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070065 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
66 return;
67
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080068 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070069 (mDpy == 0) ? "\"PRIMARY\"" :
70 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070071 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
72 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080073 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
74 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
75 (mCurrentFrame.needsRedraw? "YES" : "NO"),
76 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070077 if(isDisplaySplit(ctx, mDpy)) {
78 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
79 "Right: [%d, %d, %d, %d] \n",
80 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
81 ctx->listStats[mDpy].lRoi.right,
82 ctx->listStats[mDpy].lRoi.bottom,
83 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
84 ctx->listStats[mDpy].rRoi.right,
85 ctx->listStats[mDpy].rRoi.bottom);
86 } else {
87 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
88 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
89 ctx->listStats[mDpy].lRoi.right,
90 ctx->listStats[mDpy].lRoi.bottom);
91 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080092 dumpsys_log(buf," --------------------------------------------- \n");
93 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
94 dumpsys_log(buf," --------------------------------------------- \n");
95 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
96 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
97 index,
98 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070099 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800100 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700101 (mCurrentFrame.drop[index] ? "DROP" :
102 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800103 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
104 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
105 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800106}
107
108bool MDPComp::init(hwc_context_t *ctx) {
109
110 if(!ctx) {
111 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
112 return false;
113 }
114
Saurabh Shah59562ff2014-09-30 16:13:12 -0700115 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800116
117 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530118 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
119 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800120 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
121 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800122 sEnabled = true;
123 }
124
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700125 sEnableMixedMode = true;
126 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
127 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
128 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
129 sEnableMixedMode = false;
130 }
131
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700132 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
133
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800134 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700135 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700136 int val = atoi(property);
137 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700138 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800139 }
140
Saurabh Shahacec8e42014-11-25 11:07:04 -0800141 /* Maximum layers allowed to use MDP on secondary panels. If property
142 * doesn't exist, default to 1. Using the property it can be set to 0 or
143 * more.
144 */
145 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
146 int val = atoi(property);
147 sMaxSecLayers = (val >= 0) ? val : 1;
148 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
149 }
150
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400151 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700152 sIdleInvalidator = IdleInvalidator::getInstance();
153 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
154 delete sIdleInvalidator;
155 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400156 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800157 }
radhakrishnac9a67412013-09-25 17:40:42 +0530158
Saurabh Shah7c727642014-06-02 15:47:14 -0700159 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700160 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700161 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
162 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
163 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530164 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530165 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700166
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530167 bool defaultPTOR = false;
168 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
169 //8x16 and 8x39 targets by default
170 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
171 (qdutils::MDPVersion::getInstance().is8x16() ||
172 qdutils::MDPVersion::getInstance().is8x39())) {
173 defaultPTOR = true;
174 }
175
176 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
177 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700178 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
179 HWC_DISPLAY_PRIMARY);
180 }
181
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530182 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
183 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
184 enablePartialUpdateForMDP3 = true;
185 }
186
187 if(!enablePartialUpdateForMDP3 &&
188 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
189 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
190 enablePartialUpdateForMDP3 = true;
191 }
192
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700193 return true;
194}
195
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800196void MDPComp::reset(hwc_context_t *ctx) {
197 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700198 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800199 ctx->mOverlay->clear(mDpy);
200 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700201}
202
Raj Kamal4393eaa2014-06-06 13:45:20 +0530203void MDPComp::reset() {
204 sHandleTimeout = false;
205 mModeOn = false;
206}
207
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700208void MDPComp::timeout_handler(void *udata) {
209 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
210
211 if(!ctx) {
212 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
213 return;
214 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800215 Locker::Autolock _l(ctx->mDrawLock);
216 // Handle timeout event only if the previous composition is MDP or MIXED.
217 if(!sHandleTimeout) {
218 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
219 return;
220 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700221 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700222 ALOGE("%s: HWC proc not registered", __FUNCTION__);
223 return;
224 }
225 sIdleFallBack = true;
226 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700227 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228}
229
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700230void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
231 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800232 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700233 if(value > maxSupported) {
234 ALOGW("%s: Input exceeds max value supported. Setting to"
235 "max value: %d", __FUNCTION__, maxSupported);
236 }
237 sMaxPipesPerMixer = min(value, maxSupported);
238}
239
Saurabh Shah59562ff2014-09-30 16:13:12 -0700240void MDPComp::setIdleTimeout(const uint32_t& timeout) {
241 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
242
243 if(sIdleInvalidator) {
244 if(timeout <= ONE_REFRESH_PERIOD_MS) {
245 //If the specified timeout is < 1 draw cycle worth, "virtually"
246 //disable idle timeout. The ideal way for clients to disable
247 //timeout is to set it to 0
248 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
249 ALOGI("Disabled idle timeout");
250 return;
251 }
252 sIdleInvalidator->setIdleTimeout(timeout);
253 ALOGI("Idle timeout set to %u", timeout);
254 } else {
255 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
256 }
257}
258
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800259void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260 hwc_display_contents_1_t* list) {
261 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800262
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800263 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800264 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800265 if(!mCurrentFrame.isFBComposed[index]) {
266 layerProp[index].mFlags |= HWC_MDPCOMP;
267 layer->compositionType = HWC_OVERLAY;
268 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800269 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700270 /* Drop the layer when its already present in FB OR when it lies
271 * outside frame's ROI */
272 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800273 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700274 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800275 }
276 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700277}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500278
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800279void MDPComp::setRedraw(hwc_context_t *ctx,
280 hwc_display_contents_1_t* list) {
281 mCurrentFrame.needsRedraw = false;
282 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
283 (list->flags & HWC_GEOMETRY_CHANGED) ||
284 isSkipPresent(ctx, mDpy)) {
285 mCurrentFrame.needsRedraw = true;
286 }
287}
288
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800289MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700290 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700291 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800292}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800293
Saurabh Shahaa236822013-04-24 18:07:26 -0700294void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700295 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 if(mdpToLayer[i].pipeInfo) {
297 delete mdpToLayer[i].pipeInfo;
298 mdpToLayer[i].pipeInfo = NULL;
299 //We dont own the rotator
300 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800301 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800302 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800303
304 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
305 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700306 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800307
Saurabh Shahaa236822013-04-24 18:07:26 -0700308 layerCount = numLayers;
309 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800310 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700311 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800312 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800313}
314
Saurabh Shahaa236822013-04-24 18:07:26 -0700315void MDPComp::FrameInfo::map() {
316 // populate layer and MDP maps
317 int mdpIdx = 0;
318 for(int idx = 0; idx < layerCount; idx++) {
319 if(!isFBComposed[idx]) {
320 mdpToLayer[mdpIdx].listIndex = idx;
321 layerToMDP[idx] = mdpIdx++;
322 }
323 }
324}
325
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800326MDPComp::LayerCache::LayerCache() {
327 reset();
328}
329
330void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700331 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530332 memset(&isFBComposed, true, sizeof(isFBComposed));
333 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800334 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700335}
336
337void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530338 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700339 for(int i = 0; i < numAppLayers; i++) {
340 hnd[i] = list->hwLayers[i].handle;
341 }
342}
343
344void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700345 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530346 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
347 memcpy(&drop, &curFrame.drop, sizeof(drop));
348}
349
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800350bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
351 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530352 if(layerCount != curFrame.layerCount)
353 return false;
354 for(int i = 0; i < curFrame.layerCount; i++) {
355 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
356 (curFrame.drop[i] != drop[i])) {
357 return false;
358 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800359 if(curFrame.isFBComposed[i] &&
360 (hnd[i] != list->hwLayers[i].handle)){
361 return false;
362 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530363 }
364 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800365}
366
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700367bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
368 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800369 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700370 (not isValidDimension(ctx,layer))
371 //More conditions here, SKIP, sRGB+Blend etc
372 ) {
373 return false;
374 }
375 return true;
376}
377
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530378bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800379 private_handle_t *hnd = (private_handle_t *)layer->handle;
380
381 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700382 if (layer->flags & HWC_COLOR_FILL) {
383 // Color layer
384 return true;
385 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700386 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800387 return false;
388 }
389
Naseer Ahmede850a802013-09-06 13:12:52 -0400390 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400391 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400392 return false;
393
Saurabh Shah62e1d732013-09-17 10:44:05 -0700394 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700395 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700396 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700397 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
398 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 int dst_w = dst.right - dst.left;
400 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800401 float w_scale = ((float)crop_w / (float)dst_w);
402 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530403 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700404
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800405 /* Workaround for MDP HW limitation in DSI command mode panels where
406 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
407 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530408 * There also is a HW limilation in MDP, minimum block size is 2x2
409 * Fallback to GPU if height is less than 2.
410 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700411 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800412 return false;
413
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800414 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530415 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800416 const float w_dscale = w_scale;
417 const float h_dscale = h_scale;
418
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800419 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700420
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530421 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700422 /* On targets that doesnt support Decimation (eg.,8x26)
423 * maximum downscale support is overlay pipe downscale.
424 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400425 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530426 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700427 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800428 return false;
429 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700430 // Decimation on macrotile format layers is not supported.
431 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530432 /* Bail out if
433 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700434 * 2. exceeds maximum downscale limit
435 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400436 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530437 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700438 w_dscale > maxMDPDownscale ||
439 h_dscale > maxMDPDownscale) {
440 return false;
441 }
442 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800443 return false;
444 }
445 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700446 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700447 return false;
448 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700449 }
450
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800451 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530452 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800453 const float w_uscale = 1.0f / w_scale;
454 const float h_uscale = 1.0f / h_scale;
455
456 if(w_uscale > upscale || h_uscale > upscale)
457 return false;
458 }
459
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800460 return true;
461}
462
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800463bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700464 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800465
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800466 if(!isEnabled()) {
467 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700468 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530469 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530470 qdutils::MDPVersion::getInstance().is8x16() ||
471 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800472 ctx->mVideoTransFlag &&
473 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700474 //1 Padding round to shift pipes across mixers
475 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
476 __FUNCTION__);
477 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700478 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
479 /* TODO: freeing up all the resources only for the targets having total
480 number of pipes < 8. Need to analyze number of VIG pipes used
481 for primary in previous draw cycle and accordingly decide
482 whether to fall back to full GPU comp or video only comp
483 */
484 if(isSecondaryConfiguring(ctx)) {
485 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
486 __FUNCTION__);
487 ret = false;
488 } else if(ctx->isPaddingRound) {
489 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
490 __FUNCTION__,mDpy);
491 ret = false;
492 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800493 } else if (ctx->isDMAStateChanging) {
494 // Bail out if a padding round has been invoked in order to switch DMA
495 // state to block mode. We need this to cater for the case when a layer
496 // requires rotation in the current frame.
497 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
498 __FUNCTION__);
499 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700500 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800501
Saurabh Shahaa236822013-04-24 18:07:26 -0700502 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800503}
504
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800505void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
506 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
507 fbRect = getIntersection(fbRect, roi);
508}
509
510/* 1) Identify layers that are not visible or lying outside the updating ROI and
511 * drop them from composition.
512 * 2) If we have a scaling layer which needs cropping against generated
513 * ROI, reset ROI to full resolution. */
514bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
515 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700516 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800517 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800518
519 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800520 if(!isValidRect(visibleRect)) {
521 mCurrentFrame.drop[i] = true;
522 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800523 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800524 }
525
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700526 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700527 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800528 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700530 if(!isValidRect(res)) {
531 mCurrentFrame.drop[i] = true;
532 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534 /* Reset frame ROI when any layer which needs scaling also needs ROI
535 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800536 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800537 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700538 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
539 mCurrentFrame.dropCount = 0;
540 return false;
541 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800542
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800543 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530544 if (layer->blending == HWC_BLENDING_NONE &&
545 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800546 visibleRect = deductRect(visibleRect, res);
547 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700548 }
549 return true;
550}
551
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800552/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
553 * are updating. If DirtyRegion is applicable, calculate it by accounting all
554 * the changing layer's dirtyRegion. */
555void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
556 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700557 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800558 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700559 return;
560
561 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800562 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
563 (int)ctx->dpyAttr[mDpy].yres};
564
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700565 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800566 hwc_layer_1_t* layer = &list->hwLayers[index];
567 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800568 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700569 hwc_rect_t dst = layer->displayFrame;
570 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800571
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800572#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800573 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700574 {
575 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
576 int x_off = dst.left - src.left;
577 int y_off = dst.top - src.top;
578 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
579 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800580#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800581
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800582 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700583 }
584 }
585
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800586 /* No layer is updating. Still SF wants a refresh.*/
587 if(!isValidRect(roi))
588 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800589
590 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800591 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800592
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800593 ctx->listStats[mDpy].lRoi = roi;
594 if(!validateAndApplyROI(ctx, list))
595 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700596
597 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800598 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
599 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
600}
601
602void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
603 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
604 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
605
606 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
607 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
608 fbRect = getUnion(l_fbRect, r_fbRect);
609}
610/* 1) Identify layers that are not visible or lying outside BOTH the updating
611 * ROI's and drop them from composition. If a layer is spanning across both
612 * the halves of the screen but needed by only ROI, the non-contributing
613 * half will not be programmed for MDP.
614 * 2) If we have a scaling layer which needs cropping against generated
615 * ROI, reset ROI to full resolution. */
616bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
617 hwc_display_contents_1_t* list) {
618
619 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
620
621 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
622 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
623
624 for(int i = numAppLayers - 1; i >= 0; i--){
625 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
626 {
627 mCurrentFrame.drop[i] = true;
628 mCurrentFrame.dropCount++;
629 continue;
630 }
631
632 const hwc_layer_1_t* layer = &list->hwLayers[i];
633 hwc_rect_t dstRect = layer->displayFrame;
634
635 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
636 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
637 hwc_rect_t res = getUnion(l_res, r_res);
638
639 if(!isValidRect(l_res) && !isValidRect(r_res)) {
640 mCurrentFrame.drop[i] = true;
641 mCurrentFrame.dropCount++;
642 } else {
643 /* Reset frame ROI when any layer which needs scaling also needs ROI
644 * cropping */
645 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
646 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
647 mCurrentFrame.dropCount = 0;
648 return false;
649 }
650
radhakrishna4efbdd62014-11-03 13:19:27 +0530651 if (layer->blending == HWC_BLENDING_NONE &&
652 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800653 visibleRectL = deductRect(visibleRectL, l_res);
654 visibleRectR = deductRect(visibleRectR, r_res);
655 }
656 }
657 }
658 return true;
659}
660/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
661 * are updating. If DirtyRegion is applicable, calculate it by accounting all
662 * the changing layer's dirtyRegion. */
663void MDPCompSplit::generateROI(hwc_context_t *ctx,
664 hwc_display_contents_1_t* list) {
665 if(!canPartialUpdate(ctx, list))
666 return;
667
668 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
669 int lSplit = getLeftSplit(ctx, mDpy);
670
671 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
672 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
673
674 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
675 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
676
677 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
678 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
679
680 for(int index = 0; index < numAppLayers; index++ ) {
681 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800682 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800683 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800684 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700685 hwc_rect_t dst = layer->displayFrame;
686 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800687
688#ifdef QCOM_BSP
689 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700690 {
691 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
692 int x_off = dst.left - src.left;
693 int y_off = dst.top - src.top;
694 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
695 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800696#endif
697
698 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
699 if(isValidRect(l_dst))
700 l_roi = getUnion(l_roi, l_dst);
701
702 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
703 if(isValidRect(r_dst))
704 r_roi = getUnion(r_roi, r_dst);
705 }
706 }
707
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700708 /* For panels that cannot accept commands in both the interfaces, we cannot
709 * send two ROI's (for each half). We merge them into single ROI and split
710 * them across lSplit for MDP mixer use. The ROI's will be merged again
711 * finally before udpating the panel in the driver. */
712 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
713 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
714 l_roi = getIntersection(temp_roi, l_frame);
715 r_roi = getIntersection(temp_roi, r_frame);
716 }
717
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800718 /* No layer is updating. Still SF wants a refresh. */
719 if(!isValidRect(l_roi) && !isValidRect(r_roi))
720 return;
721
722 l_roi = getSanitizeROI(l_roi, l_frame);
723 r_roi = getSanitizeROI(r_roi, r_frame);
724
725 ctx->listStats[mDpy].lRoi = l_roi;
726 ctx->listStats[mDpy].rRoi = r_roi;
727
728 if(!validateAndApplyROI(ctx, list))
729 resetROI(ctx, mDpy);
730
731 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
732 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
733 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
734 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
735 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
736 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700737}
738
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800739/* Checks for conditions where all the layers marked for MDP comp cannot be
740 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800741bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800742 hwc_display_contents_1_t* list){
743
Saurabh Shahaa236822013-04-24 18:07:26 -0700744 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800745
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700746 // Fall back to video only composition, if AIV video mode is enabled
747 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700748 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
749 __FUNCTION__, mDpy);
750 return false;
751 }
752
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400753 // No Idle fall back, if secure display or secure RGB layers are present or
754 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700755 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400756 !ctx->listStats[mDpy].secureRGBCount) &&
757 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700758 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
759 return false;
760 }
761
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800762 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700763 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
764 __FUNCTION__,
765 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800766 return false;
767 }
768
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700769 // if secondary is configuring or Padding round, fall back to video only
770 // composition and release all assigned non VIG pipes from primary.
771 if(isSecondaryConfiguring(ctx)) {
772 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
773 __FUNCTION__);
774 return false;
775 } else if(ctx->isPaddingRound) {
776 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
777 __FUNCTION__,mDpy);
778 return false;
779 }
780
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700781 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800782 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700783 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800784 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
785 return false;
786 }
787
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800788 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800789 hwc_layer_1_t* layer = &list->hwLayers[i];
790 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800791
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800792 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700793 if(!canUseRotator(ctx, mDpy)) {
794 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
795 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700796 return false;
797 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800798 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530799
800 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
801 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800802 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700803 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530804 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
805 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
806 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800807 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700808
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700809 if(ctx->mAD->isDoable()) {
810 return false;
811 }
812
Saurabh Shahaa236822013-04-24 18:07:26 -0700813 //If all above hard conditions are met we can do full or partial MDP comp.
814 bool ret = false;
815 if(fullMDPComp(ctx, list)) {
816 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700817 } else if(fullMDPCompWithPTOR(ctx, list)) {
818 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700819 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700820 ret = true;
821 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530822
Saurabh Shahaa236822013-04-24 18:07:26 -0700823 return ret;
824}
825
826bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700827
828 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
829 return false;
830
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700831 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
832 for(int i = 0; i < numAppLayers; i++) {
833 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700834 if(not mCurrentFrame.drop[i] and
835 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700836 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
837 return false;
838 }
839 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800840
Saurabh Shahaa236822013-04-24 18:07:26 -0700841 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700842 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
843 sizeof(mCurrentFrame.isFBComposed));
844 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
845 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700846
Raj Kamal389d6e32014-08-04 14:43:24 +0530847 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800848 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530849 }
850
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800851 if(!postHeuristicsHandling(ctx, list)) {
852 ALOGD_IF(isDebug(), "post heuristic handling failed");
853 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700854 return false;
855 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700856 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
857 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700858 return true;
859}
860
Sushil Chauhandefd3522014-05-13 18:17:12 -0700861/* Full MDP Composition with Peripheral Tiny Overlap Removal.
862 * MDP bandwidth limitations can be avoided, if the overlap region
863 * covered by the smallest layer at a higher z-order, gets composed
864 * by Copybit on a render buffer, which can be queued to MDP.
865 */
866bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
867 hwc_display_contents_1_t* list) {
868
869 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
870 const int stagesForMDP = min(sMaxPipesPerMixer,
871 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
872
873 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700874 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700875 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
876 return false;
877 }
878
879 // Frame level checks
880 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
881 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
882 isSecurePresent(ctx, mDpy)) {
883 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
884 return false;
885 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700886 // MDP comp checks
887 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700888 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700889 if(not isSupportedForMDPComp(ctx, layer)) {
890 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
891 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700892 }
893 }
894
Sushil Chauhandefd3522014-05-13 18:17:12 -0700895 /* We cannot use this composition mode, if:
896 1. A below layer needs scaling.
897 2. Overlap is not peripheral to display.
898 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700899 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700900 */
901
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700902 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
903 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
904 memset(overlapRect, 0, sizeof(overlapRect));
905 int layerPixelCount, minPixelCount = 0;
906 int numPTORLayersFound = 0;
907 for (int i = numAppLayers-1; (i >= 0 &&
908 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700909 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700912 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
913 // PTOR layer should be peripheral and cannot have transform
914 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
915 has90Transform(layer)) {
916 continue;
917 }
918 if((3 * (layerPixelCount + minPixelCount)) >
919 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
920 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
921 continue;
922 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700923 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700924 for (int j = i-1; j >= 0; j--) {
925 // Check if the layers below this layer qualifies for PTOR comp
926 hwc_layer_1_t* layer = &list->hwLayers[j];
927 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700928 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700929 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700930 if (isValidRect(getIntersection(dispFrame, disFrame))) {
931 if (has90Transform(layer) || needsScaling(layer)) {
932 found = false;
933 break;
934 }
935 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700936 }
937 }
938 // Store the minLayer Index
939 if(found) {
940 minLayerIndex[numPTORLayersFound] = i;
941 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
942 minPixelCount += layerPixelCount;
943 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700944 }
945 }
946
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700947 // No overlap layers
948 if (!numPTORLayersFound)
949 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700950
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 // Store the displayFrame and the sourceCrops of the layers
952 hwc_rect_t displayFrame[numAppLayers];
953 hwc_rect_t sourceCrop[numAppLayers];
954 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700955 hwc_layer_1_t* layer = &list->hwLayers[i];
956 displayFrame[i] = layer->displayFrame;
957 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700958 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530960 /**
961 * It's possible that 2 PTOR layers might have overlapping.
962 * In such case, remove the intersection(again if peripheral)
963 * from the lower PTOR layer to avoid overlapping.
964 * If intersection is not on peripheral then compromise
965 * by reducing number of PTOR layers.
966 **/
967 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
968 if(isValidRect(commonRect)) {
969 overlapRect[1] = deductRect(overlapRect[1], commonRect);
970 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
971 }
972
973 ctx->mPtorInfo.count = numPTORLayersFound;
974 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
975 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
976 }
977
978 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
979 // reset PTOR
980 ctx->mPtorInfo.count = 0;
981 if(isValidRect(commonRect)) {
982 // If PTORs are intersecting restore displayframe of PTOR[1]
983 // before returning, as we have modified it above.
984 list->hwLayers[minLayerIndex[1]].displayFrame =
985 displayFrame[minLayerIndex[1]];
986 }
987 return false;
988 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700989 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
990 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
991
Xu Yangcda012c2014-07-30 21:57:21 +0800992 // Store the blending mode, planeAlpha, and transform of PTOR layers
993 int32_t blending[numPTORLayersFound];
994 uint8_t planeAlpha[numPTORLayersFound];
995 uint32_t transform[numPTORLayersFound];
996
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700997 for(int j = 0; j < numPTORLayersFound; j++) {
998 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700999
1000 // Update src crop of PTOR layer
1001 hwc_layer_1_t* layer = &list->hwLayers[index];
1002 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1003 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1004 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1005 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1006
1007 // Store & update w, h, format of PTOR layer
1008 private_handle_t *hnd = (private_handle_t *)layer->handle;
1009 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1010 layerWhf[j] = whf;
1011 hnd->width = renderBuf->width;
1012 hnd->height = renderBuf->height;
1013 hnd->format = renderBuf->format;
1014
Xu Yangcda012c2014-07-30 21:57:21 +08001015 // Store & update blending mode, planeAlpha and transform of PTOR layer
1016 blending[j] = layer->blending;
1017 planeAlpha[j] = layer->planeAlpha;
1018 transform[j] = layer->transform;
1019 layer->blending = HWC_BLENDING_NONE;
1020 layer->planeAlpha = 0xFF;
1021 layer->transform = 0;
1022
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001023 // Remove overlap from crop & displayFrame of below layers
1024 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001025 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001026 if(!isValidRect(getIntersection(layer->displayFrame,
1027 overlapRect[j]))) {
1028 continue;
1029 }
1030 // Update layer attributes
1031 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1032 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301033 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001034 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1035 layer->transform);
1036 layer->sourceCropf.left = (float)srcCrop.left;
1037 layer->sourceCropf.top = (float)srcCrop.top;
1038 layer->sourceCropf.right = (float)srcCrop.right;
1039 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1040 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001041 }
1042
1043 mCurrentFrame.mdpCount = numAppLayers;
1044 mCurrentFrame.fbCount = 0;
1045 mCurrentFrame.fbZ = -1;
1046
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301047 for (int j = 0; j < numAppLayers; j++) {
1048 if(isValidRect(list->hwLayers[j].displayFrame)) {
1049 mCurrentFrame.isFBComposed[j] = false;
1050 } else {
1051 mCurrentFrame.mdpCount--;
1052 mCurrentFrame.drop[j] = true;
1053 }
1054 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001055
1056 bool result = postHeuristicsHandling(ctx, list);
1057
1058 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001059 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001060 hwc_layer_1_t* layer = &list->hwLayers[i];
1061 layer->displayFrame = displayFrame[i];
1062 layer->sourceCropf.left = (float)sourceCrop[i].left;
1063 layer->sourceCropf.top = (float)sourceCrop[i].top;
1064 layer->sourceCropf.right = (float)sourceCrop[i].right;
1065 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1066 }
1067
Xu Yangcda012c2014-07-30 21:57:21 +08001068 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001069 for (int i = 0; i < numPTORLayersFound; i++) {
1070 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001071 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001072 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1073 hnd->width = layerWhf[i].w;
1074 hnd->height = layerWhf[i].h;
1075 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001076 layer->blending = blending[i];
1077 layer->planeAlpha = planeAlpha[i];
1078 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001079 }
1080
Sushil Chauhandefd3522014-05-13 18:17:12 -07001081 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001082 // reset PTOR
1083 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001084 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001085 } else {
1086 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1087 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001088 }
1089
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001090 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1091 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001092 return result;
1093}
1094
Saurabh Shahaa236822013-04-24 18:07:26 -07001095bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1096{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001097 if(!sEnableMixedMode) {
1098 //Mixed mode is disabled. No need to even try caching.
1099 return false;
1100 }
1101
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001102 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001103 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001104 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001105 cacheBasedComp(ctx, list);
1106 } else {
1107 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001108 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001109 }
1110
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001111 return ret;
1112}
1113
1114bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1115 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001116 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1117 return false;
1118
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001119 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001120 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001121 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001122
1123 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1124 for(int i = 0; i < numAppLayers; i++) {
1125 if(!mCurrentFrame.isFBComposed[i]) {
1126 hwc_layer_1_t* layer = &list->hwLayers[i];
1127 if(not isSupportedForMDPComp(ctx, layer)) {
1128 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1129 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001130 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001131 return false;
1132 }
1133 }
1134 }
1135
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001136 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001137 /* mark secure RGB layers for MDP comp */
1138 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301139 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001140 if(!ret) {
1141 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001142 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001143 return false;
1144 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001145
1146 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001147
Raj Kamal389d6e32014-08-04 14:43:24 +05301148 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001149 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301150 }
1151
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001152 if(!postHeuristicsHandling(ctx, list)) {
1153 ALOGD_IF(isDebug(), "post heuristic handling failed");
1154 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001155 return false;
1156 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001157 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1158 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001159
Saurabh Shahaa236822013-04-24 18:07:26 -07001160 return true;
1161}
1162
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001163bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001164 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001165 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1166 return false;
1167
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001168 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001169 return false;
1170 }
1171
Saurabh Shahb772ae32013-11-18 15:40:02 -08001172 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001173 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1174 const int stagesForMDP = min(sMaxPipesPerMixer,
1175 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001176
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001177 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1178 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1179 int lastMDPSupportedIndex = numAppLayers;
1180 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001181
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001182 //Find the minimum MDP batch size
1183 for(int i = 0; i < numAppLayers;i++) {
1184 if(mCurrentFrame.drop[i]) {
1185 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001186 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001187 }
1188 hwc_layer_1_t* layer = &list->hwLayers[i];
1189 if(not isSupportedForMDPComp(ctx, layer)) {
1190 lastMDPSupportedIndex = i;
1191 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1192 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001193 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001194 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001195 }
1196
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001197 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1198 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1199 mCurrentFrame.dropCount);
1200
1201 //Start at a point where the fb batch should at least have 2 layers, for
1202 //this mode to be justified.
1203 while(fbBatchSize < 2) {
1204 ++fbBatchSize;
1205 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001206 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001207
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001208 //If there are no layers for MDP, this mode doesnt make sense.
1209 if(mdpBatchSize < 1) {
1210 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1211 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001212 return false;
1213 }
1214
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001215 mCurrentFrame.reset(numAppLayers);
1216
1217 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1218 while(mdpBatchSize > 0) {
1219 //Mark layers for MDP comp
1220 int mdpBatchLeft = mdpBatchSize;
1221 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1222 if(mCurrentFrame.drop[i]) {
1223 continue;
1224 }
1225 mCurrentFrame.isFBComposed[i] = false;
1226 --mdpBatchLeft;
1227 }
1228
1229 mCurrentFrame.fbZ = mdpBatchSize;
1230 mCurrentFrame.fbCount = fbBatchSize;
1231 mCurrentFrame.mdpCount = mdpBatchSize;
1232
1233 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1234 __FUNCTION__, mdpBatchSize, fbBatchSize,
1235 mCurrentFrame.dropCount);
1236
1237 if(postHeuristicsHandling(ctx, list)) {
1238 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001239 __FUNCTION__);
1240 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1241 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001242 return true;
1243 }
1244
1245 reset(ctx);
1246 --mdpBatchSize;
1247 ++fbBatchSize;
1248 }
1249
1250 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001251}
1252
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001253bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301254 if(mDpy or isSecurePresent(ctx, mDpy) or
1255 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001256 return false;
1257 }
1258 return true;
1259}
1260
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001261bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1262 hwc_display_contents_1_t* list){
1263 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1264 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1265 mDpy ) {
1266 return false;
1267 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001268 if(ctx->listStats[mDpy].secureUI)
1269 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001270 return true;
1271}
1272
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001273bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1274 hwc_display_contents_1_t* list) {
1275 const bool secureOnly = true;
1276 return videoOnlyComp(ctx, list, not secureOnly) or
1277 videoOnlyComp(ctx, list, secureOnly);
1278}
1279
1280bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001281 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001282 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1283 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001284 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001285
Saurabh Shahaa236822013-04-24 18:07:26 -07001286 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001287 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001288 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001289 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001290
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001291 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1292 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001293 return false;
1294 }
1295
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001296 /* Bail out if we are processing only secured video layers
1297 * and we dont have any */
1298 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001299 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001300 return false;
1301 }
1302
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001303 if(mCurrentFrame.fbCount)
1304 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001305
Raj Kamal389d6e32014-08-04 14:43:24 +05301306 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001307 adjustForSourceSplit(ctx, list);
1308 }
1309
1310 if(!postHeuristicsHandling(ctx, list)) {
1311 ALOGD_IF(isDebug(), "post heuristic handling failed");
1312 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001313 return false;
1314 }
1315
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001316 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1317 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001318 return true;
1319}
1320
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001321/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1322bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1323 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001324 // Fall back to video only composition, if AIV video mode is enabled
1325 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001326 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1327 __FUNCTION__, mDpy);
1328 return false;
1329 }
1330
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001331 const bool secureOnly = true;
1332 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1333 mdpOnlyLayersComp(ctx, list, secureOnly);
1334
1335}
1336
1337bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1338 hwc_display_contents_1_t* list, bool secureOnly) {
1339
1340 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1341 return false;
1342
1343 /* Bail out if we are processing only secured video layers
1344 * and we dont have any */
1345 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1346 reset(ctx);
1347 return false;
1348 }
1349
1350 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1351 mCurrentFrame.reset(numAppLayers);
1352 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1353
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001354 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001355 /* mark secure RGB layers for MDP comp */
1356 updateSecureRGB(ctx, list);
1357
1358 if(mCurrentFrame.mdpCount == 0) {
1359 reset(ctx);
1360 return false;
1361 }
1362
1363 /* find the maximum batch of layers to be marked for framebuffer */
1364 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1365 if(!ret) {
1366 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1367 reset(ctx);
1368 return false;
1369 }
1370
1371 if(sEnableYUVsplit){
1372 adjustForSourceSplit(ctx, list);
1373 }
1374
1375 if(!postHeuristicsHandling(ctx, list)) {
1376 ALOGD_IF(isDebug(), "post heuristic handling failed");
1377 reset(ctx);
1378 return false;
1379 }
1380
1381 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1382 __FUNCTION__);
1383 return true;
1384}
1385
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001386/* Checks for conditions where YUV layers cannot be bypassed */
1387bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001388 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001389 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001390 return false;
1391 }
1392
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001393 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001394 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1395 return false;
1396 }
1397
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001398 if(isSecuring(ctx, layer)) {
1399 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1400 return false;
1401 }
1402
Saurabh Shah4fdde762013-04-30 18:47:33 -07001403 if(!isValidDimension(ctx, layer)) {
1404 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1405 __FUNCTION__);
1406 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001407 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001408
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001409 if(layer->planeAlpha < 0xFF) {
1410 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1411 in video only mode",
1412 __FUNCTION__);
1413 return false;
1414 }
1415
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001416 return true;
1417}
1418
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001419/* Checks for conditions where Secure RGB layers cannot be bypassed */
1420bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1421 if(isSkipLayer(layer)) {
1422 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1423 __FUNCTION__, mDpy);
1424 return false;
1425 }
1426
1427 if(isSecuring(ctx, layer)) {
1428 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1429 return false;
1430 }
1431
1432 if(not isSupportedForMDPComp(ctx, layer)) {
1433 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1434 __FUNCTION__);
1435 return false;
1436 }
1437 return true;
1438}
1439
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301440/* starts at fromIndex and check for each layer to find
1441 * if it it has overlapping with any Updating layer above it in zorder
1442 * till the end of the batch. returns true if it finds any intersection */
1443bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1444 int fromIndex, int toIndex) {
1445 for(int i = fromIndex; i < toIndex; i++) {
1446 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1447 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1448 return false;
1449 }
1450 }
1451 }
1452 return true;
1453}
1454
1455/* Checks if given layer at targetLayerIndex has any
1456 * intersection with all the updating layers in beween
1457 * fromIndex and toIndex. Returns true if it finds intersectiion */
1458bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1459 int fromIndex, int toIndex, int targetLayerIndex) {
1460 for(int i = fromIndex; i <= toIndex; i++) {
1461 if(!mCurrentFrame.isFBComposed[i]) {
1462 if(areLayersIntersecting(&list->hwLayers[i],
1463 &list->hwLayers[targetLayerIndex])) {
1464 return true;
1465 }
1466 }
1467 }
1468 return false;
1469}
1470
1471int MDPComp::getBatch(hwc_display_contents_1_t* list,
1472 int& maxBatchStart, int& maxBatchEnd,
1473 int& maxBatchCount) {
1474 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301475 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001476 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301477 while (i < mCurrentFrame.layerCount) {
1478 int batchCount = 0;
1479 int batchStart = i;
1480 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001481 /* Adjust batch Z order with the dropped layers so far */
1482 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301483 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301484 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301485 while(i < mCurrentFrame.layerCount) {
1486 if(!mCurrentFrame.isFBComposed[i]) {
1487 if(!batchCount) {
1488 i++;
1489 break;
1490 }
1491 updatingLayersAbove++;
1492 i++;
1493 continue;
1494 } else {
1495 if(mCurrentFrame.drop[i]) {
1496 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001497 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301498 continue;
1499 } else if(updatingLayersAbove <= 0) {
1500 batchCount++;
1501 batchEnd = i;
1502 i++;
1503 continue;
1504 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1505
1506 // We have a valid updating layer already. If layer-i not
1507 // have overlapping with all updating layers in between
1508 // batch-start and i, then we can add layer i to batch.
1509 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1510 batchCount++;
1511 batchEnd = i;
1512 i++;
1513 continue;
1514 } else if(canPushBatchToTop(list, batchStart, i)) {
1515 //If All the non-updating layers with in this batch
1516 //does not have intersection with the updating layers
1517 //above in z-order, then we can safely move the batch to
1518 //higher z-order. Increment fbZ as it is moving up.
1519 if( firstZReverseIndex < 0) {
1520 firstZReverseIndex = i;
1521 }
1522 batchCount++;
1523 batchEnd = i;
1524 fbZ += updatingLayersAbove;
1525 i++;
1526 updatingLayersAbove = 0;
1527 continue;
1528 } else {
1529 //both failed.start the loop again from here.
1530 if(firstZReverseIndex >= 0) {
1531 i = firstZReverseIndex;
1532 }
1533 break;
1534 }
1535 }
1536 }
1537 }
1538 if(batchCount > maxBatchCount) {
1539 maxBatchCount = batchCount;
1540 maxBatchStart = batchStart;
1541 maxBatchEnd = batchEnd;
1542 fbZOrder = fbZ;
1543 }
1544 }
1545 return fbZOrder;
1546}
1547
1548bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1549 hwc_display_contents_1_t* list) {
1550 /* Idea is to keep as many non-updating(cached) layers in FB and
1551 * send rest of them through MDP. This is done in 2 steps.
1552 * 1. Find the maximum contiguous batch of non-updating layers.
1553 * 2. See if we can improve this batch size for caching by adding
1554 * opaque layers around the batch, if they don't have
1555 * any overlapping with the updating layers in between.
1556 * NEVER mark an updating layer for caching.
1557 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001558
1559 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001560 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001561 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301562 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001563
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001564 /* Nothing is cached. No batching needed */
1565 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001566 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001567 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001568
1569 /* No MDP comp layers, try to use other comp modes */
1570 if(mCurrentFrame.mdpCount == 0) {
1571 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001572 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001573
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301574 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001575
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301576 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001578 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001579 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001581 if(!mCurrentFrame.drop[i]){
1582 //If an unsupported layer is being attempted to
1583 //be pulled out we should fail
1584 if(not isSupportedForMDPComp(ctx, layer)) {
1585 return false;
1586 }
1587 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001588 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001589 }
1590 }
1591
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301592 // update the frame data
1593 mCurrentFrame.fbZ = fbZ;
1594 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001595 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001596 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001597
1598 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301599 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001600
1601 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001603
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001605 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001607 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001609 for(int i = 0; i < numAppLayers; i++) {
1610 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001611 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001612 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001613 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001614 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001615 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616 }
1617 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001618
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001619 frame.fbCount = fbCount;
1620 frame.mdpCount = frame.layerCount - frame.fbCount
1621 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001622
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001623 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1624 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001625}
1626
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001627// drop other non-AIV layers from external display list.
1628void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001629 hwc_display_contents_1_t* list) {
1630 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1631 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001632 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001633 mCurrentFrame.dropCount++;
1634 mCurrentFrame.drop[i] = true;
1635 }
1636 }
1637 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1638 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1639 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1640 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1641 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1642 mCurrentFrame.dropCount);
1643}
1644
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001645void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001646 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001647 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1648 for(int index = 0;index < nYuvCount; index++){
1649 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1650 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1651
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001652 if(mCurrentFrame.drop[nYuvIndex]) {
1653 continue;
1654 }
1655
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001657 if(!frame.isFBComposed[nYuvIndex]) {
1658 frame.isFBComposed[nYuvIndex] = true;
1659 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660 }
1661 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001662 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001663 private_handle_t *hnd = (private_handle_t *)layer->handle;
1664 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001665 frame.isFBComposed[nYuvIndex] = false;
1666 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001667 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001668 }
1669 }
1670 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001671
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001672 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1673 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001674}
1675
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001676void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1677 hwc_display_contents_1_t* list) {
1678 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1679 for(int index = 0;index < nSecureRGBCount; index++){
1680 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1681 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1682
1683 if(!isSecureRGBDoable(ctx, layer)) {
1684 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1685 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1686 mCurrentFrame.fbCount++;
1687 }
1688 } else {
1689 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1690 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1691 mCurrentFrame.fbCount--;
1692 }
1693 }
1694 }
1695
1696 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1697 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1698 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1699 mCurrentFrame.fbCount);
1700}
1701
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001702hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1703 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001704 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001705
1706 /* Update only the region of FB needed for composition */
1707 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1708 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1709 hwc_layer_1_t* layer = &list->hwLayers[i];
1710 hwc_rect_t dst = layer->displayFrame;
1711 fbRect = getUnion(fbRect, dst);
1712 }
1713 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001714 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001715 return fbRect;
1716}
1717
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001718bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1719 hwc_display_contents_1_t* list) {
1720
1721 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001722 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001723 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1724 return false;
1725 }
1726
1727 //Limitations checks
1728 if(!hwLimitationsCheck(ctx, list)) {
1729 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1730 return false;
1731 }
1732
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001733 //Configure framebuffer first if applicable
1734 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001735 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001736 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1737 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001738 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1739 __FUNCTION__);
1740 return false;
1741 }
1742 }
1743
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001744 mCurrentFrame.map();
1745
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001746 if(!allocLayerPipes(ctx, list)) {
1747 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001748 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001749 }
1750
1751 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001752 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001753 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001754 int mdpIndex = mCurrentFrame.layerToMDP[index];
1755 hwc_layer_1_t* layer = &list->hwLayers[index];
1756
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301757 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1758 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1759 mdpNextZOrder++;
1760 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001761 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1762 cur_pipe->zOrder = mdpNextZOrder++;
1763
radhakrishnac9a67412013-09-25 17:40:42 +05301764 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301765 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301766 if(configure4k2kYuv(ctx, layer,
1767 mCurrentFrame.mdpToLayer[mdpIndex])
1768 != 0 ){
1769 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1770 for layer %d",__FUNCTION__, index);
1771 return false;
1772 }
1773 else{
1774 mdpNextZOrder++;
1775 }
1776 continue;
1777 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001778 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1779 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301780 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001781 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001782 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001783 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 }
1785
Saurabh Shaha36be922013-12-16 18:18:39 -08001786 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1787 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1788 ,__FUNCTION__, mDpy);
1789 return false;
1790 }
1791
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001792 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001793 return true;
1794}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001795
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001796bool MDPComp::resourceCheck(hwc_context_t* ctx,
1797 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001798 const bool fbUsed = mCurrentFrame.fbCount;
1799 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1800 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1801 return false;
1802 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001803
1804 //Will benefit cases where a video has non-updating background.
1805 if((mDpy > HWC_DISPLAY_PRIMARY) and
1806 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1807 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1808 return false;
1809 }
1810
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001811 // Init rotCount to number of rotate sessions used by other displays
1812 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1813 // Count the number of rotator sessions required for current display
1814 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1815 if(!mCurrentFrame.isFBComposed[index]) {
1816 hwc_layer_1_t* layer = &list->hwLayers[index];
1817 private_handle_t *hnd = (private_handle_t *)layer->handle;
1818 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1819 rotCount++;
1820 }
1821 }
1822 }
1823 // if number of layers to rotate exceeds max rotator sessions, bail out.
1824 if(rotCount > RotMgr::MAX_ROT_SESS) {
1825 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1826 __FUNCTION__, mDpy);
1827 return false;
1828 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001829 return true;
1830}
1831
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301832bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1833 hwc_display_contents_1_t* list) {
1834
1835 //A-family hw limitation:
1836 //If a layer need alpha scaling, MDP can not support.
1837 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1838 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1839 if(!mCurrentFrame.isFBComposed[i] &&
1840 isAlphaScaled( &list->hwLayers[i])) {
1841 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1842 return false;
1843 }
1844 }
1845 }
1846
1847 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1848 //If multiple layers requires downscaling and also they are overlapping
1849 //fall back to GPU since MDSS can not handle it.
1850 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1851 qdutils::MDPVersion::getInstance().is8x26()) {
1852 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1853 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1854 if(!mCurrentFrame.isFBComposed[i] &&
1855 isDownscaleRequired(botLayer)) {
1856 //if layer-i is marked for MDP and needs downscaling
1857 //check if any MDP layer on top of i & overlaps with layer-i
1858 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1859 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1860 if(!mCurrentFrame.isFBComposed[j] &&
1861 isDownscaleRequired(topLayer)) {
1862 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1863 topLayer->displayFrame);
1864 if(isValidRect(r))
1865 return false;
1866 }
1867 }
1868 }
1869 }
1870 }
1871 return true;
1872}
1873
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001874int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001875 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001876 char property[PROPERTY_VALUE_MAX];
1877
Raj Kamal4393eaa2014-06-06 13:45:20 +05301878 if(!ctx || !list) {
1879 ALOGE("%s: Invalid context or list",__FUNCTION__);
1880 mCachedFrame.reset();
1881 return -1;
1882 }
1883
1884 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001885 if(mDpy == HWC_DISPLAY_PRIMARY) {
1886 sSimulationFlags = 0;
1887 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1888 int currentFlags = atoi(property);
1889 if(currentFlags != sSimulationFlags) {
1890 sSimulationFlags = currentFlags;
1891 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1892 sSimulationFlags, sSimulationFlags);
1893 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001894 }
1895 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001896 // reset PTOR
1897 if(!mDpy)
1898 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001899
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301900 //Do not cache the information for next draw cycle.
1901 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1902 ALOGI("%s: Unsupported layer count for mdp composition",
1903 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001904 mCachedFrame.reset();
1905 return -1;
1906 }
1907
Saurabh Shahb39f8152013-08-22 10:21:44 -07001908 //reset old data
1909 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001910 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1911 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301912
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001913 // Detect the start of animation and fall back to GPU only once to cache
1914 // all the layers in FB and display FB content untill animation completes.
1915 if(ctx->listStats[mDpy].isDisplayAnimating) {
1916 mCurrentFrame.needsRedraw = false;
1917 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1918 mCurrentFrame.needsRedraw = true;
1919 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1920 }
1921 setMDPCompLayerFlags(ctx, list);
1922 mCachedFrame.updateCounts(mCurrentFrame);
1923 ret = -1;
1924 return ret;
1925 } else {
1926 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1927 }
1928
Saurabh Shahb39f8152013-08-22 10:21:44 -07001929 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001930 if(isFrameDoable(ctx)) {
1931 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001932 // if AIV Video mode is enabled, drop all non AIV layers from the
1933 // external display list.
1934 if(ctx->listStats[mDpy].mAIVVideoMode) {
1935 dropNonAIVLayers(ctx, list);
1936 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001937
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001938 // if tryFullFrame fails, try to push all video and secure RGB layers
1939 // to MDP for composition.
1940 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001941 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301942 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001943 setMDPCompLayerFlags(ctx, list);
1944 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001945 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001946 reset(ctx);
1947 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1948 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001949 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001950 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1951 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001952 }
1953 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301954 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1955 enablePartialUpdateForMDP3) {
1956 generateROI(ctx, list);
1957 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1958 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1959 }
1960 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001961 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1962 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001963 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001964 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001965
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001966 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001967 ALOGD("GEOMETRY change: %d",
1968 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001969 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001970 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001971 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001972 }
1973
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001974#ifdef DYNAMIC_FPS
1975 //For primary display, set the dynamic refreshrate
Raj Kamal0d53fc62014-11-25 17:36:36 +05301976 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1977 ctx->mUseMetaDataRefreshRate) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001978 FrameInfo frame;
1979 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301980 memset(&frame.drop, 0, sizeof(frame.drop));
1981 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001982 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1983 __FUNCTION__);
1984 updateLayerCache(ctx, list, frame);
1985 updateYUV(ctx, list, false /*secure only*/, frame);
1986 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1987 //Set the new fresh rate, if there is only one updating YUV layer
1988 //or there is one single RGB layer with this request
1989 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1990 (frame.layerCount == 1)) {
1991 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1992 }
1993 setRefreshRate(ctx, mDpy, refreshRate);
1994 }
1995#endif
1996
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001997 mCachedFrame.cacheAll(list);
1998 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001999 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002000}
2001
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002002bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302003
2004 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302005 int mdpIndex = mCurrentFrame.layerToMDP[index];
2006 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2007 info.pipeInfo = new MdpYUVPipeInfo;
2008 info.rot = NULL;
2009 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302010
2011 pipe_info.lIndex = ovutils::OV_INVALID;
2012 pipe_info.rIndex = ovutils::OV_INVALID;
2013
Saurabh Shahc62f3982014-03-05 14:28:26 -08002014 Overlay::PipeSpecs pipeSpecs;
2015 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2016 pipeSpecs.needsScaling = true;
2017 pipeSpecs.dpy = mDpy;
2018 pipeSpecs.fb = false;
2019
2020 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302021 if(pipe_info.lIndex == ovutils::OV_INVALID){
2022 bRet = false;
2023 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2024 __FUNCTION__);
2025 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002026 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302027 if(pipe_info.rIndex == ovutils::OV_INVALID){
2028 bRet = false;
2029 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2030 __FUNCTION__);
2031 }
2032 return bRet;
2033}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002034
2035int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2036 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002037 if (ctx->mPtorInfo.isActive()) {
2038 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002039 if (fd < 0) {
2040 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002041 }
2042 }
2043 return fd;
2044}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002045//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002046
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002047void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302048 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002049 //If 4k2k Yuv layer split is possible, and if
2050 //fbz is above 4k2k layer, increment fb zorder by 1
2051 //as we split 4k2k layer and increment zorder for right half
2052 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002053 if(!ctx)
2054 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002055 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302056 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2057 index++) {
2058 if(!mCurrentFrame.isFBComposed[index]) {
2059 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2060 mdpNextZOrder++;
2061 }
2062 mdpNextZOrder++;
2063 hwc_layer_1_t* layer = &list->hwLayers[index];
2064 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302065 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302066 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2067 mCurrentFrame.fbZ += 1;
2068 mdpNextZOrder++;
2069 //As we split 4kx2k yuv layer and program to 2 VG pipes
2070 //(if available) increase mdpcount by 1.
2071 mCurrentFrame.mdpCount++;
2072 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002073 }
2074 }
2075 }
radhakrishnac9a67412013-09-25 17:40:42 +05302076}
2077
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002078/*
2079 * Configures pipe(s) for MDP composition
2080 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002081int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002082 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002083 MdpPipeInfoNonSplit& mdp_info =
2084 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302085 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002086 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002087 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002088
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002089 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2090 __FUNCTION__, layer, zOrder, dest);
2091
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002092 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002093 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002094}
2095
Saurabh Shah88e4d272013-09-03 13:31:29 -07002096bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002097 hwc_display_contents_1_t* list) {
2098 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002099
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002100 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002101
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002102 hwc_layer_1_t* layer = &list->hwLayers[index];
2103 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302104 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002105 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302106 continue;
2107 }
2108 }
2109
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002110 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002111 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002112 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002113 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002114 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002115
Saurabh Shahc62f3982014-03-05 14:28:26 -08002116 Overlay::PipeSpecs pipeSpecs;
2117 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2118 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2119 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2120 (qdutils::MDPVersion::getInstance().is8x26() and
2121 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2122 pipeSpecs.dpy = mDpy;
2123 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002124 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002125
Saurabh Shahc62f3982014-03-05 14:28:26 -08002126 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2127
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002128 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002129 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002130 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002131 }
2132 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002133 return true;
2134}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002135
radhakrishnac9a67412013-09-25 17:40:42 +05302136int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2137 PipeLayerPair& PipeLayerPair) {
2138 MdpYUVPipeInfo& mdp_info =
2139 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2140 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302141 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302142 eDest lDest = mdp_info.lIndex;
2143 eDest rDest = mdp_info.rIndex;
2144
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002145 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302146 lDest, rDest, &PipeLayerPair.rot);
2147}
2148
Saurabh Shah88e4d272013-09-03 13:31:29 -07002149bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002150
Raj Kamal4393eaa2014-06-06 13:45:20 +05302151 if(!isEnabled() or !mModeOn) {
2152 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302153 return true;
2154 }
2155
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002156 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002157 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002158 sHandleTimeout = true;
2159 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002160
2161 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002162 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002163
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002164 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2165 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002166 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002167 if(mCurrentFrame.isFBComposed[i]) continue;
2168
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002169 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002170 private_handle_t *hnd = (private_handle_t *)layer->handle;
2171 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002172 if (!(layer->flags & HWC_COLOR_FILL)) {
2173 ALOGE("%s handle null", __FUNCTION__);
2174 return false;
2175 }
2176 // No PLAY for Color layer
2177 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2178 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002179 }
2180
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002181 int mdpIndex = mCurrentFrame.layerToMDP[i];
2182
Raj Kamal389d6e32014-08-04 14:43:24 +05302183 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302184 {
2185 MdpYUVPipeInfo& pipe_info =
2186 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2187 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2188 ovutils::eDest indexL = pipe_info.lIndex;
2189 ovutils::eDest indexR = pipe_info.rIndex;
2190 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302191 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302192 if(rot) {
2193 rot->queueBuffer(fd, offset);
2194 fd = rot->getDstMemId();
2195 offset = rot->getDstOffset();
2196 }
2197 if(indexL != ovutils::OV_INVALID) {
2198 ovutils::eDest destL = (ovutils::eDest)indexL;
2199 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2200 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2201 if (!ov.queueBuffer(fd, offset, destL)) {
2202 ALOGE("%s: queueBuffer failed for display:%d",
2203 __FUNCTION__, mDpy);
2204 return false;
2205 }
2206 }
2207
2208 if(indexR != ovutils::OV_INVALID) {
2209 ovutils::eDest destR = (ovutils::eDest)indexR;
2210 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2211 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2212 if (!ov.queueBuffer(fd, offset, destR)) {
2213 ALOGE("%s: queueBuffer failed for display:%d",
2214 __FUNCTION__, mDpy);
2215 return false;
2216 }
2217 }
2218 }
2219 else{
2220 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002221 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302222 ovutils::eDest dest = pipe_info.index;
2223 if(dest == ovutils::OV_INVALID) {
2224 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002225 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302226 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002227
radhakrishnac9a67412013-09-25 17:40:42 +05302228 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2229 continue;
2230 }
2231
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002232 int fd = hnd->fd;
2233 uint32_t offset = (uint32_t)hnd->offset;
2234 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2235 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002236 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002237 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002238 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002239 }
2240
radhakrishnac9a67412013-09-25 17:40:42 +05302241 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2242 using pipe: %d", __FUNCTION__, layer,
2243 hnd, dest );
2244
radhakrishnac9a67412013-09-25 17:40:42 +05302245 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2246 if(rot) {
2247 if(!rot->queueBuffer(fd, offset))
2248 return false;
2249 fd = rot->getDstMemId();
2250 offset = rot->getDstOffset();
2251 }
2252
2253 if (!ov.queueBuffer(fd, offset, dest)) {
2254 ALOGE("%s: queueBuffer failed for display:%d ",
2255 __FUNCTION__, mDpy);
2256 return false;
2257 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002258 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002259
2260 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002261 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002262 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002263}
2264
Saurabh Shah88e4d272013-09-03 13:31:29 -07002265//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002266
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002267void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302268 hwc_display_contents_1_t* list){
2269 //if 4kx2k yuv layer is totally present in either in left half
2270 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302271 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302272 if(mCurrentFrame.fbZ >= 0) {
2273 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2274 index++) {
2275 if(!mCurrentFrame.isFBComposed[index]) {
2276 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2277 mdpNextZOrder++;
2278 }
2279 mdpNextZOrder++;
2280 hwc_layer_1_t* layer = &list->hwLayers[index];
2281 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302282 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302283 hwc_rect_t dst = layer->displayFrame;
2284 if((dst.left > lSplit) || (dst.right < lSplit)) {
2285 mCurrentFrame.mdpCount += 1;
2286 }
2287 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2288 mCurrentFrame.fbZ += 1;
2289 mdpNextZOrder++;
2290 }
2291 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002292 }
radhakrishnac9a67412013-09-25 17:40:42 +05302293 }
2294}
2295
Saurabh Shah88e4d272013-09-03 13:31:29 -07002296bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002297 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002298
Saurabh Shahc62f3982014-03-05 14:28:26 -08002299 const int lSplit = getLeftSplit(ctx, mDpy);
2300 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002301 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002302 pipe_info.lIndex = ovutils::OV_INVALID;
2303 pipe_info.rIndex = ovutils::OV_INVALID;
2304
Saurabh Shahc62f3982014-03-05 14:28:26 -08002305 Overlay::PipeSpecs pipeSpecs;
2306 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2307 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2308 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2309 pipeSpecs.dpy = mDpy;
2310 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2311 pipeSpecs.fb = false;
2312
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002313 // Acquire pipe only for the updating half
2314 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2315 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2316
2317 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002318 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002319 if(pipe_info.lIndex == ovutils::OV_INVALID)
2320 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002321 }
2322
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002323 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002324 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2325 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002326 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002327 return false;
2328 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002329
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002330 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002331}
2332
Saurabh Shah88e4d272013-09-03 13:31:29 -07002333bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002334 hwc_display_contents_1_t* list) {
2335 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002336
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002337 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002338
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002339 hwc_layer_1_t* layer = &list->hwLayers[index];
2340 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302341 hwc_rect_t dst = layer->displayFrame;
2342 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302343 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302344 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002345 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302346 continue;
2347 }
2348 }
2349 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002350 int mdpIndex = mCurrentFrame.layerToMDP[index];
2351 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002352 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002353 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002354 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002355
Saurabh Shahc62f3982014-03-05 14:28:26 -08002356 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2357 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2358 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002359 return false;
2360 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002361 }
2362 return true;
2363}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002364
radhakrishnac9a67412013-09-25 17:40:42 +05302365int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2366 PipeLayerPair& PipeLayerPair) {
2367 const int lSplit = getLeftSplit(ctx, mDpy);
2368 hwc_rect_t dst = layer->displayFrame;
2369 if((dst.left > lSplit)||(dst.right < lSplit)){
2370 MdpYUVPipeInfo& mdp_info =
2371 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2372 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302373 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302374 eDest lDest = mdp_info.lIndex;
2375 eDest rDest = mdp_info.rIndex;
2376
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002377 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302378 lDest, rDest, &PipeLayerPair.rot);
2379 }
2380 else{
2381 return configure(ctx, layer, PipeLayerPair);
2382 }
2383}
2384
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002385/*
2386 * Configures pipe(s) for MDP composition
2387 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002388int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002389 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002390 MdpPipeInfoSplit& mdp_info =
2391 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002392 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302393 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002394 eDest lDest = mdp_info.lIndex;
2395 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002396
2397 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2398 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2399
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002400 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002401 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002402}
2403
Saurabh Shah88e4d272013-09-03 13:31:29 -07002404bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002405
Raj Kamal4393eaa2014-06-06 13:45:20 +05302406 if(!isEnabled() or !mModeOn) {
2407 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302408 return true;
2409 }
2410
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002411 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002412 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002413 sHandleTimeout = true;
2414 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002415
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002416 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002417 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002418
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002419 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2420 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002421 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002422 if(mCurrentFrame.isFBComposed[i]) continue;
2423
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002424 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002425 private_handle_t *hnd = (private_handle_t *)layer->handle;
2426 if(!hnd) {
2427 ALOGE("%s handle null", __FUNCTION__);
2428 return false;
2429 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002430
2431 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2432 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002433 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002434
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002435 int mdpIndex = mCurrentFrame.layerToMDP[i];
2436
Raj Kamal389d6e32014-08-04 14:43:24 +05302437 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302438 {
2439 MdpYUVPipeInfo& pipe_info =
2440 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2441 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2442 ovutils::eDest indexL = pipe_info.lIndex;
2443 ovutils::eDest indexR = pipe_info.rIndex;
2444 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302445 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302446 if(rot) {
2447 rot->queueBuffer(fd, offset);
2448 fd = rot->getDstMemId();
2449 offset = rot->getDstOffset();
2450 }
2451 if(indexL != ovutils::OV_INVALID) {
2452 ovutils::eDest destL = (ovutils::eDest)indexL;
2453 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2454 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2455 if (!ov.queueBuffer(fd, offset, destL)) {
2456 ALOGE("%s: queueBuffer failed for display:%d",
2457 __FUNCTION__, mDpy);
2458 return false;
2459 }
2460 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002461
radhakrishnac9a67412013-09-25 17:40:42 +05302462 if(indexR != ovutils::OV_INVALID) {
2463 ovutils::eDest destR = (ovutils::eDest)indexR;
2464 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2465 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2466 if (!ov.queueBuffer(fd, offset, destR)) {
2467 ALOGE("%s: queueBuffer failed for display:%d",
2468 __FUNCTION__, mDpy);
2469 return false;
2470 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002471 }
2472 }
radhakrishnac9a67412013-09-25 17:40:42 +05302473 else{
2474 MdpPipeInfoSplit& pipe_info =
2475 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2476 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002477
radhakrishnac9a67412013-09-25 17:40:42 +05302478 ovutils::eDest indexL = pipe_info.lIndex;
2479 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002480
radhakrishnac9a67412013-09-25 17:40:42 +05302481 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002482 uint32_t offset = (uint32_t)hnd->offset;
2483 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2484 if (!mDpy && (index != -1)) {
2485 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2486 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002487 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002488 }
radhakrishnac9a67412013-09-25 17:40:42 +05302489
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002490 if(ctx->mAD->draw(ctx, fd, offset)) {
2491 fd = ctx->mAD->getDstFd();
2492 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002493 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002494
radhakrishnac9a67412013-09-25 17:40:42 +05302495 if(rot) {
2496 rot->queueBuffer(fd, offset);
2497 fd = rot->getDstMemId();
2498 offset = rot->getDstOffset();
2499 }
2500
2501 //************* play left mixer **********
2502 if(indexL != ovutils::OV_INVALID) {
2503 ovutils::eDest destL = (ovutils::eDest)indexL;
2504 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2505 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2506 if (!ov.queueBuffer(fd, offset, destL)) {
2507 ALOGE("%s: queueBuffer failed for left mixer",
2508 __FUNCTION__);
2509 return false;
2510 }
2511 }
2512
2513 //************* play right mixer **********
2514 if(indexR != ovutils::OV_INVALID) {
2515 ovutils::eDest destR = (ovutils::eDest)indexR;
2516 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2517 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2518 if (!ov.queueBuffer(fd, offset, destR)) {
2519 ALOGE("%s: queueBuffer failed for right mixer",
2520 __FUNCTION__);
2521 return false;
2522 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002523 }
2524 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002525
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002526 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2527 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002528
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002529 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002530}
Saurabh Shahab47c692014-02-12 18:45:57 -08002531
2532//================MDPCompSrcSplit==============================================
2533bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002534 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002535 private_handle_t *hnd = (private_handle_t *)layer->handle;
2536 hwc_rect_t dst = layer->displayFrame;
2537 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2538 pipe_info.lIndex = ovutils::OV_INVALID;
2539 pipe_info.rIndex = ovutils::OV_INVALID;
2540
2541 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2542 //should have a higher priority than the right one. Pipe priorities are
2543 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002544
Saurabh Shahc62f3982014-03-05 14:28:26 -08002545 Overlay::PipeSpecs pipeSpecs;
2546 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2547 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2548 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2549 pipeSpecs.dpy = mDpy;
2550 pipeSpecs.fb = false;
2551
Saurabh Shahab47c692014-02-12 18:45:57 -08002552 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002553 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002554 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002555 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002556 }
2557
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002558 /* Use 2 pipes IF
2559 a) Layer's crop width is > 2048 or
2560 b) Layer's dest width > 2048 or
2561 c) On primary, driver has indicated with caps to split always. This is
2562 based on an empirically derived value of panel height. Applied only
2563 if the layer's width is > mixer's width
2564 */
2565
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302566 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002567 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302568 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002569 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2570 const uint32_t dstWidth = dst.right - dst.left;
2571 const uint32_t dstHeight = dst.bottom - dst.top;
2572 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002573 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002574 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2575 crop.bottom - crop.top;
2576 //Approximation to actual clock, ignoring the common factors in pipe and
2577 //mixer cases like line_time
2578 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2579 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002580
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002581 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2582 //pipe line length, we are still using 2 pipes. This is fine just because
2583 //this is source split where destination doesn't matter. Evaluate later to
2584 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002585 if(dstWidth > mdpHw.getMaxMixerWidth() or
2586 cropWidth > mdpHw.getMaxMixerWidth() or
2587 (primarySplitAlways and
2588 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002589 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002590 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002591 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002592 }
2593
2594 // Return values
2595 // 1 Left pipe is higher priority, do nothing.
2596 // 0 Pipes of same priority.
2597 //-1 Right pipe is of higher priority, needs swap.
2598 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2599 pipe_info.rIndex) == -1) {
2600 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002601 }
2602 }
2603
2604 return true;
2605}
2606
Saurabh Shahab47c692014-02-12 18:45:57 -08002607int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2608 PipeLayerPair& PipeLayerPair) {
2609 private_handle_t *hnd = (private_handle_t *)layer->handle;
2610 if(!hnd) {
2611 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2612 return -1;
2613 }
2614 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2615 MdpPipeInfoSplit& mdp_info =
2616 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2617 Rotator **rot = &PipeLayerPair.rot;
2618 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002619 eDest lDest = mdp_info.lIndex;
2620 eDest rDest = mdp_info.rIndex;
2621 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2622 hwc_rect_t dst = layer->displayFrame;
2623 int transform = layer->transform;
2624 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002625 int rotFlags = ROT_FLAGS_NONE;
2626 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2627 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2628
2629 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2630 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2631
2632 // Handle R/B swap
2633 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2634 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2635 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2636 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2637 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2638 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002639 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002640 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2641 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002642 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002643 /* Calculate the external display position based on MDP downscale,
2644 ActionSafe, and extorientation features. */
2645 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002646
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002647 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302648 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002649 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002650
2651 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2652 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002653 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002654 }
2655
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002656 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002657 (*rot) = ctx->mRotMgr->getNext();
2658 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002659 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002660 //If the video is using a single pipe, enable BWC
2661 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002662 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2663 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002664 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002665 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002666 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002667 ALOGE("%s: configRotator failed!", __FUNCTION__);
2668 return -1;
2669 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002670 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002671 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002672 }
2673
2674 //If 2 pipes being used, divide layer into half, crop and dst
2675 hwc_rect_t cropL = crop;
2676 hwc_rect_t cropR = crop;
2677 hwc_rect_t dstL = dst;
2678 hwc_rect_t dstR = dst;
2679 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2680 cropL.right = (crop.right + crop.left) / 2;
2681 cropR.left = cropL.right;
2682 sanitizeSourceCrop(cropL, cropR, hnd);
2683
Saurabh Shahb729b192014-08-15 18:04:24 -07002684 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002685 //Swap crops on H flip since 2 pipes are being used
2686 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2687 hwc_rect_t tmp = cropL;
2688 cropL = cropR;
2689 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002690 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002691 }
2692
Saurabh Shahb729b192014-08-15 18:04:24 -07002693 //cropSwap trick: If the src and dst widths are both odd, let us say
2694 //2507, then splitting both into half would cause left width to be 1253
2695 //and right 1254. If crop is swapped because of H flip, this will cause
2696 //left crop width to be 1254, whereas left dst width remains 1253, thus
2697 //inducing a scaling that is unaccounted for. To overcome that we add 1
2698 //to the dst width if there is a cropSwap. So if the original width was
2699 //2507, the left dst width will be 1254. Even if the original width was
2700 //even for ex: 2508, the left dst width will still remain 1254.
2701 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002702 dstR.left = dstL.right;
2703 }
2704
2705 //For the mdp, since either we are pre-rotating or MDP does flips
2706 orient = OVERLAY_TRANSFORM_0;
2707 transform = 0;
2708
2709 //configure left pipe
2710 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002711 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002712 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2713 (ovutils::eBlending) getBlending(layer->blending));
2714
2715 if(configMdp(ctx->mOverlay, pargL, orient,
2716 cropL, dstL, metadata, lDest) < 0) {
2717 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2718 return -1;
2719 }
2720 }
2721
2722 //configure right pipe
2723 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002724 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002725 static_cast<eRotFlags>(rotFlags),
2726 layer->planeAlpha,
2727 (ovutils::eBlending) getBlending(layer->blending));
2728 if(configMdp(ctx->mOverlay, pargR, orient,
2729 cropR, dstR, metadata, rDest) < 0) {
2730 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2731 return -1;
2732 }
2733 }
2734
2735 return 0;
2736}
2737
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002738}; //namespace
2739