blob: 4a04f60b803ecef7a148304fa2c1af70dbdb92ba [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"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070029#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080030
Saurabh Shah85234ec2013-04-12 17:09:00 -070031using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070032using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080033using namespace overlay::utils;
34namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036namespace qhwc {
37
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080038//==============MDPComp========================================================
39
Saurabh Shah59562ff2014-09-30 16:13:12 -070040IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070041bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080042bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070043bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050044bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070045bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070046int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070047int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053048bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070049bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080050int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053051bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070052bool MDPComp::sIsPartialUpdateActive = true;
Saurabh Shah88e4d272013-09-03 13:31:29 -070053MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070054 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
55 sSrcSplitEnabled = true;
56 return new MDPCompSrcSplit(dpy);
57 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070058 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080059 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070060 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080061}
62
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080063MDPComp::MDPComp(int dpy):mDpy(dpy){};
64
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070065void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080066{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070067 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
68 return;
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070071 (mDpy == 0) ? "\"PRIMARY\"" :
72 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070073 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
74 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080075 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
76 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
77 (mCurrentFrame.needsRedraw? "YES" : "NO"),
78 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070079 if(isDisplaySplit(ctx, mDpy)) {
80 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
81 "Right: [%d, %d, %d, %d] \n",
82 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
83 ctx->listStats[mDpy].lRoi.right,
84 ctx->listStats[mDpy].lRoi.bottom,
85 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
86 ctx->listStats[mDpy].rRoi.right,
87 ctx->listStats[mDpy].rRoi.bottom);
88 } else {
89 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
90 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
91 ctx->listStats[mDpy].lRoi.right,
92 ctx->listStats[mDpy].lRoi.bottom);
93 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080094 dumpsys_log(buf," --------------------------------------------- \n");
95 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
96 dumpsys_log(buf," --------------------------------------------- \n");
97 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
98 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
99 index,
100 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700101 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700103 (mCurrentFrame.drop[index] ? "DROP" :
104 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800105 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
106 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
107 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800108}
109
110bool MDPComp::init(hwc_context_t *ctx) {
111
112 if(!ctx) {
113 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
114 return false;
115 }
116
Saurabh Shah59562ff2014-09-30 16:13:12 -0700117 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800118
119 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530120 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
121 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800122 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
123 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800124 sEnabled = true;
125 }
126
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700127 sEnableMixedMode = true;
128 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
131 sEnableMixedMode = false;
132 }
133
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700134 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
135
136 /* MDSS_MDP_STAGE_UNUSED and MDSS_MDP_STAGE_BASE are not available for MDP
137 * composition. */
138 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages() - 2;
139 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700140 int val = atoi(property);
141 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700142 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800143 }
144
Saurabh Shahacec8e42014-11-25 11:07:04 -0800145 /* Maximum layers allowed to use MDP on secondary panels. If property
146 * doesn't exist, default to 1. Using the property it can be set to 0 or
147 * more.
148 */
149 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
150 int val = atoi(property);
151 sMaxSecLayers = (val >= 0) ? val : 1;
152 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
153 }
154
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400155 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700156 sIdleInvalidator = IdleInvalidator::getInstance();
157 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
158 delete sIdleInvalidator;
159 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800161 }
radhakrishnac9a67412013-09-25 17:40:42 +0530162
Saurabh Shah7c727642014-06-02 15:47:14 -0700163 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700164 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700165 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
166 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
167 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530168 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530169 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700170
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530171 bool defaultPTOR = false;
172 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
173 //8x16 and 8x39 targets by default
174 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
175 (qdutils::MDPVersion::getInstance().is8x16() ||
176 qdutils::MDPVersion::getInstance().is8x39())) {
177 defaultPTOR = true;
178 }
179
180 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
181 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700182 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
183 HWC_DISPLAY_PRIMARY);
184 }
185
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530186 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
187 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
188 enablePartialUpdateForMDP3 = true;
189 }
190
191 if(!enablePartialUpdateForMDP3 &&
192 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
193 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
194 enablePartialUpdateForMDP3 = true;
195 }
196
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800197 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
198
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700199 return true;
200}
201
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800202void MDPComp::reset(hwc_context_t *ctx) {
203 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700204 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800205 ctx->mOverlay->clear(mDpy);
206 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700207}
208
Raj Kamal4393eaa2014-06-06 13:45:20 +0530209void MDPComp::reset() {
210 sHandleTimeout = false;
211 mModeOn = false;
212}
213
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700214void MDPComp::timeout_handler(void *udata) {
215 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
216
217 if(!ctx) {
218 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
219 return;
220 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800221 Locker::Autolock _l(ctx->mDrawLock);
222 // Handle timeout event only if the previous composition is MDP or MIXED.
223 if(!sHandleTimeout) {
224 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
225 return;
226 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700227 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228 ALOGE("%s: HWC proc not registered", __FUNCTION__);
229 return;
230 }
231 sIdleFallBack = true;
232 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700233 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700234}
235
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700236void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
237 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
238 uint32_t maxSupported = (int)mdpVersion.getBlendStages() - 2;
239 if(value > maxSupported) {
240 ALOGW("%s: Input exceeds max value supported. Setting to"
241 "max value: %d", __FUNCTION__, maxSupported);
242 }
243 sMaxPipesPerMixer = min(value, maxSupported);
244}
245
Saurabh Shah59562ff2014-09-30 16:13:12 -0700246void MDPComp::setIdleTimeout(const uint32_t& timeout) {
247 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
248
249 if(sIdleInvalidator) {
250 if(timeout <= ONE_REFRESH_PERIOD_MS) {
251 //If the specified timeout is < 1 draw cycle worth, "virtually"
252 //disable idle timeout. The ideal way for clients to disable
253 //timeout is to set it to 0
254 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
255 ALOGI("Disabled idle timeout");
256 return;
257 }
258 sIdleInvalidator->setIdleTimeout(timeout);
259 ALOGI("Idle timeout set to %u", timeout);
260 } else {
261 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
262 }
263}
264
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800265void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800266 hwc_display_contents_1_t* list) {
267 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800268
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800269 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800270 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800271 if(!mCurrentFrame.isFBComposed[index]) {
272 layerProp[index].mFlags |= HWC_MDPCOMP;
273 layer->compositionType = HWC_OVERLAY;
274 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800275 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700276 /* Drop the layer when its already present in FB OR when it lies
277 * outside frame's ROI */
278 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800279 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700280 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800281 }
282 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700283}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500284
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800285void MDPComp::setRedraw(hwc_context_t *ctx,
286 hwc_display_contents_1_t* list) {
287 mCurrentFrame.needsRedraw = false;
288 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
289 (list->flags & HWC_GEOMETRY_CHANGED) ||
290 isSkipPresent(ctx, mDpy)) {
291 mCurrentFrame.needsRedraw = true;
292 }
293}
294
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800295MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700296 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700297 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800298}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800299
Saurabh Shahaa236822013-04-24 18:07:26 -0700300void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700301 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800302 if(mdpToLayer[i].pipeInfo) {
303 delete mdpToLayer[i].pipeInfo;
304 mdpToLayer[i].pipeInfo = NULL;
305 //We dont own the rotator
306 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800307 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800308 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800309
310 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
311 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700312 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800313
Saurabh Shahaa236822013-04-24 18:07:26 -0700314 layerCount = numLayers;
315 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800316 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700317 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800318 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800319}
320
Saurabh Shahaa236822013-04-24 18:07:26 -0700321void MDPComp::FrameInfo::map() {
322 // populate layer and MDP maps
323 int mdpIdx = 0;
324 for(int idx = 0; idx < layerCount; idx++) {
325 if(!isFBComposed[idx]) {
326 mdpToLayer[mdpIdx].listIndex = idx;
327 layerToMDP[idx] = mdpIdx++;
328 }
329 }
330}
331
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800332MDPComp::LayerCache::LayerCache() {
333 reset();
334}
335
336void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700337 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530338 memset(&isFBComposed, true, sizeof(isFBComposed));
339 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800340 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700341}
342
343void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530344 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700345 for(int i = 0; i < numAppLayers; i++) {
346 hnd[i] = list->hwLayers[i].handle;
347 }
348}
349
350void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700351 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530352 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
353 memcpy(&drop, &curFrame.drop, sizeof(drop));
354}
355
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800356bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
357 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530358 if(layerCount != curFrame.layerCount)
359 return false;
360 for(int i = 0; i < curFrame.layerCount; i++) {
361 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
362 (curFrame.drop[i] != drop[i])) {
363 return false;
364 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800365 if(curFrame.isFBComposed[i] &&
366 (hnd[i] != list->hwLayers[i].handle)){
367 return false;
368 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530369 }
370 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800371}
372
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700373bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
374 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800375 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700376 (not isValidDimension(ctx,layer))
377 //More conditions here, SKIP, sRGB+Blend etc
378 ) {
379 return false;
380 }
381 return true;
382}
383
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530384bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800385 private_handle_t *hnd = (private_handle_t *)layer->handle;
386
387 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700388 if (layer->flags & HWC_COLOR_FILL) {
389 // Color layer
390 return true;
391 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700392 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800393 return false;
394 }
395
Naseer Ahmede850a802013-09-06 13:12:52 -0400396 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400397 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400398 return false;
399
Saurabh Shah62e1d732013-09-17 10:44:05 -0700400 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700401 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700402 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700403 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
404 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700405 int dst_w = dst.right - dst.left;
406 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800407 float w_scale = ((float)crop_w / (float)dst_w);
408 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530409 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700410
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800411 /* Workaround for MDP HW limitation in DSI command mode panels where
412 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
413 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530414 * There also is a HW limilation in MDP, minimum block size is 2x2
415 * Fallback to GPU if height is less than 2.
416 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700417 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800418 return false;
419
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800420 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530421 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800422 const float w_dscale = w_scale;
423 const float h_dscale = h_scale;
424
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800425 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700426
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530427 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700428 /* On targets that doesnt support Decimation (eg.,8x26)
429 * maximum downscale support is overlay pipe downscale.
430 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400431 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530432 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700433 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800434 return false;
435 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700436 // Decimation on macrotile format layers is not supported.
437 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530438 /* Bail out if
439 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700440 * 2. exceeds maximum downscale limit
441 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400442 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530443 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700444 w_dscale > maxMDPDownscale ||
445 h_dscale > maxMDPDownscale) {
446 return false;
447 }
448 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800449 return false;
450 }
451 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700452 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700453 return false;
454 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700455 }
456
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800457 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530458 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800459 const float w_uscale = 1.0f / w_scale;
460 const float h_uscale = 1.0f / h_scale;
461
462 if(w_uscale > upscale || h_uscale > upscale)
463 return false;
464 }
465
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800466 return true;
467}
468
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800469bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700470 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800471
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800472 if(!isEnabled()) {
473 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700474 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530475 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530476 qdutils::MDPVersion::getInstance().is8x16() ||
477 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800478 ctx->mVideoTransFlag &&
479 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700480 //1 Padding round to shift pipes across mixers
481 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
482 __FUNCTION__);
483 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700484 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
485 /* TODO: freeing up all the resources only for the targets having total
486 number of pipes < 8. Need to analyze number of VIG pipes used
487 for primary in previous draw cycle and accordingly decide
488 whether to fall back to full GPU comp or video only comp
489 */
490 if(isSecondaryConfiguring(ctx)) {
491 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
492 __FUNCTION__);
493 ret = false;
494 } else if(ctx->isPaddingRound) {
495 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
496 __FUNCTION__,mDpy);
497 ret = false;
498 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800499 } else if (ctx->isDMAStateChanging) {
500 // Bail out if a padding round has been invoked in order to switch DMA
501 // state to block mode. We need this to cater for the case when a layer
502 // requires rotation in the current frame.
503 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
504 __FUNCTION__);
505 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700506 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800507
Saurabh Shahaa236822013-04-24 18:07:26 -0700508 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800509}
510
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800511void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
512 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
513 fbRect = getIntersection(fbRect, roi);
514}
515
516/* 1) Identify layers that are not visible or lying outside the updating ROI and
517 * drop them from composition.
518 * 2) If we have a scaling layer which needs cropping against generated
519 * ROI, reset ROI to full resolution. */
520bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
521 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700522 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800523 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800524
525 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800526 if(!isValidRect(visibleRect)) {
527 mCurrentFrame.drop[i] = true;
528 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800529 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800530 }
531
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700532 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700533 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800534 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700535
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700536 if(!isValidRect(res)) {
537 mCurrentFrame.drop[i] = true;
538 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800539 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700540 /* Reset frame ROI when any layer which needs scaling also needs ROI
541 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800542 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800543 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700544 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
545 mCurrentFrame.dropCount = 0;
546 return false;
547 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800548
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800549 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530550 if (layer->blending == HWC_BLENDING_NONE &&
551 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800552 visibleRect = deductRect(visibleRect, res);
553 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700554 }
555 return true;
556}
557
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800558/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
559 * are updating. If DirtyRegion is applicable, calculate it by accounting all
560 * the changing layer's dirtyRegion. */
561void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
562 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700563 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800564 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700565 return;
566
567 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800568 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
569 (int)ctx->dpyAttr[mDpy].yres};
570
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700571 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800572 hwc_layer_1_t* layer = &list->hwLayers[index];
573 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800574 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700575 hwc_rect_t dst = layer->displayFrame;
576 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800578#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800579 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700580 {
581 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
582 int x_off = dst.left - src.left;
583 int y_off = dst.top - src.top;
584 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
585 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800586#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800587
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800588 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700589 }
590 }
591
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800592 /* No layer is updating. Still SF wants a refresh.*/
593 if(!isValidRect(roi))
594 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800595
596 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800597 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800598
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800599 ctx->listStats[mDpy].lRoi = roi;
600 if(!validateAndApplyROI(ctx, list))
601 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700602
603 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800604 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
605 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
606}
607
608void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
609 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
610 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
611
612 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
613 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
614 fbRect = getUnion(l_fbRect, r_fbRect);
615}
616/* 1) Identify layers that are not visible or lying outside BOTH the updating
617 * ROI's and drop them from composition. If a layer is spanning across both
618 * the halves of the screen but needed by only ROI, the non-contributing
619 * half will not be programmed for MDP.
620 * 2) If we have a scaling layer which needs cropping against generated
621 * ROI, reset ROI to full resolution. */
622bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
623 hwc_display_contents_1_t* list) {
624
625 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
626
627 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
628 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
629
630 for(int i = numAppLayers - 1; i >= 0; i--){
631 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
632 {
633 mCurrentFrame.drop[i] = true;
634 mCurrentFrame.dropCount++;
635 continue;
636 }
637
638 const hwc_layer_1_t* layer = &list->hwLayers[i];
639 hwc_rect_t dstRect = layer->displayFrame;
640
641 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
642 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
643 hwc_rect_t res = getUnion(l_res, r_res);
644
645 if(!isValidRect(l_res) && !isValidRect(r_res)) {
646 mCurrentFrame.drop[i] = true;
647 mCurrentFrame.dropCount++;
648 } else {
649 /* Reset frame ROI when any layer which needs scaling also needs ROI
650 * cropping */
651 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
652 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
653 mCurrentFrame.dropCount = 0;
654 return false;
655 }
656
radhakrishna4efbdd62014-11-03 13:19:27 +0530657 if (layer->blending == HWC_BLENDING_NONE &&
658 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800659 visibleRectL = deductRect(visibleRectL, l_res);
660 visibleRectR = deductRect(visibleRectR, r_res);
661 }
662 }
663 }
664 return true;
665}
666/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
667 * are updating. If DirtyRegion is applicable, calculate it by accounting all
668 * the changing layer's dirtyRegion. */
669void MDPCompSplit::generateROI(hwc_context_t *ctx,
670 hwc_display_contents_1_t* list) {
671 if(!canPartialUpdate(ctx, list))
672 return;
673
674 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
675 int lSplit = getLeftSplit(ctx, mDpy);
676
677 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
678 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
679
680 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
681 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
682
683 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
684 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
685
686 for(int index = 0; index < numAppLayers; index++ ) {
687 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800688 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800689 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800690 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700691 hwc_rect_t dst = layer->displayFrame;
692 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800693
694#ifdef QCOM_BSP
695 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700696 {
697 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
698 int x_off = dst.left - src.left;
699 int y_off = dst.top - src.top;
700 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
701 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800702#endif
703
704 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
705 if(isValidRect(l_dst))
706 l_roi = getUnion(l_roi, l_dst);
707
708 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
709 if(isValidRect(r_dst))
710 r_roi = getUnion(r_roi, r_dst);
711 }
712 }
713
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700714 /* For panels that cannot accept commands in both the interfaces, we cannot
715 * send two ROI's (for each half). We merge them into single ROI and split
716 * them across lSplit for MDP mixer use. The ROI's will be merged again
717 * finally before udpating the panel in the driver. */
718 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
719 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
720 l_roi = getIntersection(temp_roi, l_frame);
721 r_roi = getIntersection(temp_roi, r_frame);
722 }
723
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800724 /* No layer is updating. Still SF wants a refresh. */
725 if(!isValidRect(l_roi) && !isValidRect(r_roi))
726 return;
727
728 l_roi = getSanitizeROI(l_roi, l_frame);
729 r_roi = getSanitizeROI(r_roi, r_frame);
730
731 ctx->listStats[mDpy].lRoi = l_roi;
732 ctx->listStats[mDpy].rRoi = r_roi;
733
734 if(!validateAndApplyROI(ctx, list))
735 resetROI(ctx, mDpy);
736
737 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
738 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
739 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
740 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
741 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
742 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700743}
744
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800745/* Checks for conditions where all the layers marked for MDP comp cannot be
746 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800747bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800748 hwc_display_contents_1_t* list){
749
Saurabh Shahaa236822013-04-24 18:07:26 -0700750 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800751
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700752 // Fall back to video only composition, if AIV video mode is enabled
753 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700754 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
755 __FUNCTION__, mDpy);
756 return false;
757 }
758
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400759 // No Idle fall back, if secure display or secure RGB layers are present or
760 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700761 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400762 !ctx->listStats[mDpy].secureRGBCount) &&
763 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700764 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
765 return false;
766 }
767
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800768 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700769 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
770 __FUNCTION__,
771 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800772 return false;
773 }
774
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700775 // if secondary is configuring or Padding round, fall back to video only
776 // composition and release all assigned non VIG pipes from primary.
777 if(isSecondaryConfiguring(ctx)) {
778 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
779 __FUNCTION__);
780 return false;
781 } else if(ctx->isPaddingRound) {
782 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
783 __FUNCTION__,mDpy);
784 return false;
785 }
786
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700787 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800788 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700789 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800790 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
791 return false;
792 }
793
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800794 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800795 hwc_layer_1_t* layer = &list->hwLayers[i];
796 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800797
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800798 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700799 if(!canUseRotator(ctx, mDpy)) {
800 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
801 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700802 return false;
803 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800804 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530805
806 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
807 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800808 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700809 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530810 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
811 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
812 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800813 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700814
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700815 if(ctx->mAD->isDoable()) {
816 return false;
817 }
818
Saurabh Shahaa236822013-04-24 18:07:26 -0700819 //If all above hard conditions are met we can do full or partial MDP comp.
820 bool ret = false;
821 if(fullMDPComp(ctx, list)) {
822 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700823 } else if(fullMDPCompWithPTOR(ctx, list)) {
824 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700825 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700826 ret = true;
827 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530828
Saurabh Shahaa236822013-04-24 18:07:26 -0700829 return ret;
830}
831
832bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700833
834 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
835 return false;
836
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700837 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
838 for(int i = 0; i < numAppLayers; i++) {
839 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700840 if(not mCurrentFrame.drop[i] and
841 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700842 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
843 return false;
844 }
845 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800846
Saurabh Shahaa236822013-04-24 18:07:26 -0700847 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700848 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
849 sizeof(mCurrentFrame.isFBComposed));
850 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
851 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700852
Raj Kamal389d6e32014-08-04 14:43:24 +0530853 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800854 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530855 }
856
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800857 if(!postHeuristicsHandling(ctx, list)) {
858 ALOGD_IF(isDebug(), "post heuristic handling failed");
859 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700860 return false;
861 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700862 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
863 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700864 return true;
865}
866
Sushil Chauhandefd3522014-05-13 18:17:12 -0700867/* Full MDP Composition with Peripheral Tiny Overlap Removal.
868 * MDP bandwidth limitations can be avoided, if the overlap region
869 * covered by the smallest layer at a higher z-order, gets composed
870 * by Copybit on a render buffer, which can be queued to MDP.
871 */
872bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
873 hwc_display_contents_1_t* list) {
874
875 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
876 const int stagesForMDP = min(sMaxPipesPerMixer,
877 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
878
879 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700880 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700881 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
882 return false;
883 }
884
885 // Frame level checks
886 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
887 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
888 isSecurePresent(ctx, mDpy)) {
889 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
890 return false;
891 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700892 // MDP comp checks
893 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700894 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700895 if(not isSupportedForMDPComp(ctx, layer)) {
896 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
897 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700898 }
899 }
900
Sushil Chauhandefd3522014-05-13 18:17:12 -0700901 /* We cannot use this composition mode, if:
902 1. A below layer needs scaling.
903 2. Overlap is not peripheral to display.
904 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700905 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700906 */
907
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700908 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
909 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
910 memset(overlapRect, 0, sizeof(overlapRect));
911 int layerPixelCount, minPixelCount = 0;
912 int numPTORLayersFound = 0;
913 for (int i = numAppLayers-1; (i >= 0 &&
914 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700916 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700917 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
919 // PTOR layer should be peripheral and cannot have transform
920 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
921 has90Transform(layer)) {
922 continue;
923 }
924 if((3 * (layerPixelCount + minPixelCount)) >
925 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
926 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
927 continue;
928 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700929 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700930 for (int j = i-1; j >= 0; j--) {
931 // Check if the layers below this layer qualifies for PTOR comp
932 hwc_layer_1_t* layer = &list->hwLayers[j];
933 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700934 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700935 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700936 if (isValidRect(getIntersection(dispFrame, disFrame))) {
937 if (has90Transform(layer) || needsScaling(layer)) {
938 found = false;
939 break;
940 }
941 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700942 }
943 }
944 // Store the minLayer Index
945 if(found) {
946 minLayerIndex[numPTORLayersFound] = i;
947 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
948 minPixelCount += layerPixelCount;
949 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700950 }
951 }
952
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700953 // No overlap layers
954 if (!numPTORLayersFound)
955 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700956
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700957 // Store the displayFrame and the sourceCrops of the layers
958 hwc_rect_t displayFrame[numAppLayers];
959 hwc_rect_t sourceCrop[numAppLayers];
960 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700961 hwc_layer_1_t* layer = &list->hwLayers[i];
962 displayFrame[i] = layer->displayFrame;
963 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700964 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700965
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530966 /**
967 * It's possible that 2 PTOR layers might have overlapping.
968 * In such case, remove the intersection(again if peripheral)
969 * from the lower PTOR layer to avoid overlapping.
970 * If intersection is not on peripheral then compromise
971 * by reducing number of PTOR layers.
972 **/
973 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
974 if(isValidRect(commonRect)) {
975 overlapRect[1] = deductRect(overlapRect[1], commonRect);
976 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
977 }
978
979 ctx->mPtorInfo.count = numPTORLayersFound;
980 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
981 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
982 }
983
984 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
985 // reset PTOR
986 ctx->mPtorInfo.count = 0;
987 if(isValidRect(commonRect)) {
988 // If PTORs are intersecting restore displayframe of PTOR[1]
989 // before returning, as we have modified it above.
990 list->hwLayers[minLayerIndex[1]].displayFrame =
991 displayFrame[minLayerIndex[1]];
992 }
993 return false;
994 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700995 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
996 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
997
Xu Yangcda012c2014-07-30 21:57:21 +0800998 // Store the blending mode, planeAlpha, and transform of PTOR layers
999 int32_t blending[numPTORLayersFound];
1000 uint8_t planeAlpha[numPTORLayersFound];
1001 uint32_t transform[numPTORLayersFound];
1002
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001003 for(int j = 0; j < numPTORLayersFound; j++) {
1004 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001005
1006 // Update src crop of PTOR layer
1007 hwc_layer_1_t* layer = &list->hwLayers[index];
1008 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1009 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1010 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1011 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1012
1013 // Store & update w, h, format of PTOR layer
1014 private_handle_t *hnd = (private_handle_t *)layer->handle;
1015 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1016 layerWhf[j] = whf;
1017 hnd->width = renderBuf->width;
1018 hnd->height = renderBuf->height;
1019 hnd->format = renderBuf->format;
1020
Xu Yangcda012c2014-07-30 21:57:21 +08001021 // Store & update blending mode, planeAlpha and transform of PTOR layer
1022 blending[j] = layer->blending;
1023 planeAlpha[j] = layer->planeAlpha;
1024 transform[j] = layer->transform;
1025 layer->blending = HWC_BLENDING_NONE;
1026 layer->planeAlpha = 0xFF;
1027 layer->transform = 0;
1028
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001029 // Remove overlap from crop & displayFrame of below layers
1030 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001031 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001032 if(!isValidRect(getIntersection(layer->displayFrame,
1033 overlapRect[j]))) {
1034 continue;
1035 }
1036 // Update layer attributes
1037 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1038 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301039 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001040 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1041 layer->transform);
1042 layer->sourceCropf.left = (float)srcCrop.left;
1043 layer->sourceCropf.top = (float)srcCrop.top;
1044 layer->sourceCropf.right = (float)srcCrop.right;
1045 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1046 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001047 }
1048
1049 mCurrentFrame.mdpCount = numAppLayers;
1050 mCurrentFrame.fbCount = 0;
1051 mCurrentFrame.fbZ = -1;
1052
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301053 for (int j = 0; j < numAppLayers; j++) {
1054 if(isValidRect(list->hwLayers[j].displayFrame)) {
1055 mCurrentFrame.isFBComposed[j] = false;
1056 } else {
1057 mCurrentFrame.mdpCount--;
1058 mCurrentFrame.drop[j] = true;
1059 }
1060 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001061
1062 bool result = postHeuristicsHandling(ctx, list);
1063
1064 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001065 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001066 hwc_layer_1_t* layer = &list->hwLayers[i];
1067 layer->displayFrame = displayFrame[i];
1068 layer->sourceCropf.left = (float)sourceCrop[i].left;
1069 layer->sourceCropf.top = (float)sourceCrop[i].top;
1070 layer->sourceCropf.right = (float)sourceCrop[i].right;
1071 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1072 }
1073
Xu Yangcda012c2014-07-30 21:57:21 +08001074 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001075 for (int i = 0; i < numPTORLayersFound; i++) {
1076 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001077 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001078 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1079 hnd->width = layerWhf[i].w;
1080 hnd->height = layerWhf[i].h;
1081 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001082 layer->blending = blending[i];
1083 layer->planeAlpha = planeAlpha[i];
1084 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001085 }
1086
Sushil Chauhandefd3522014-05-13 18:17:12 -07001087 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001088 // reset PTOR
1089 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001090 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001091 } else {
1092 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1093 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001094 }
1095
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001096 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1097 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001098 return result;
1099}
1100
Saurabh Shahaa236822013-04-24 18:07:26 -07001101bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1102{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001103 if(!sEnableMixedMode) {
1104 //Mixed mode is disabled. No need to even try caching.
1105 return false;
1106 }
1107
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001108 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001109 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001110 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001111 cacheBasedComp(ctx, list);
1112 } else {
1113 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001114 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001115 }
1116
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001117 return ret;
1118}
1119
1120bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1121 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001122 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1123 return false;
1124
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001125 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001126 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001127 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001128
1129 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1130 for(int i = 0; i < numAppLayers; i++) {
1131 if(!mCurrentFrame.isFBComposed[i]) {
1132 hwc_layer_1_t* layer = &list->hwLayers[i];
1133 if(not isSupportedForMDPComp(ctx, layer)) {
1134 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1135 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001136 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001137 return false;
1138 }
1139 }
1140 }
1141
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001142 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001143 /* mark secure RGB layers for MDP comp */
1144 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301145 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001146 if(!ret) {
1147 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001148 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001149 return false;
1150 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001151
1152 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001153
Raj Kamal389d6e32014-08-04 14:43:24 +05301154 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001155 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301156 }
1157
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001158 if(!postHeuristicsHandling(ctx, list)) {
1159 ALOGD_IF(isDebug(), "post heuristic handling failed");
1160 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001161 return false;
1162 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001163 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1164 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001165
Saurabh Shahaa236822013-04-24 18:07:26 -07001166 return true;
1167}
1168
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001169bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001170 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001171 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1172 return false;
1173
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001174 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001175 return false;
1176 }
1177
Saurabh Shahb772ae32013-11-18 15:40:02 -08001178 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001179 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1180 const int stagesForMDP = min(sMaxPipesPerMixer,
1181 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001182
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001183 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1184 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1185 int lastMDPSupportedIndex = numAppLayers;
1186 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001187
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001188 //Find the minimum MDP batch size
1189 for(int i = 0; i < numAppLayers;i++) {
1190 if(mCurrentFrame.drop[i]) {
1191 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001192 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001193 }
1194 hwc_layer_1_t* layer = &list->hwLayers[i];
1195 if(not isSupportedForMDPComp(ctx, layer)) {
1196 lastMDPSupportedIndex = i;
1197 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1198 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001199 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001200 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001201 }
1202
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001203 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1204 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1205 mCurrentFrame.dropCount);
1206
1207 //Start at a point where the fb batch should at least have 2 layers, for
1208 //this mode to be justified.
1209 while(fbBatchSize < 2) {
1210 ++fbBatchSize;
1211 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001212 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001213
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001214 //If there are no layers for MDP, this mode doesnt make sense.
1215 if(mdpBatchSize < 1) {
1216 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1217 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001218 return false;
1219 }
1220
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001221 mCurrentFrame.reset(numAppLayers);
1222
1223 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1224 while(mdpBatchSize > 0) {
1225 //Mark layers for MDP comp
1226 int mdpBatchLeft = mdpBatchSize;
1227 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1228 if(mCurrentFrame.drop[i]) {
1229 continue;
1230 }
1231 mCurrentFrame.isFBComposed[i] = false;
1232 --mdpBatchLeft;
1233 }
1234
1235 mCurrentFrame.fbZ = mdpBatchSize;
1236 mCurrentFrame.fbCount = fbBatchSize;
1237 mCurrentFrame.mdpCount = mdpBatchSize;
1238
1239 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1240 __FUNCTION__, mdpBatchSize, fbBatchSize,
1241 mCurrentFrame.dropCount);
1242
1243 if(postHeuristicsHandling(ctx, list)) {
1244 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001245 __FUNCTION__);
1246 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1247 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001248 return true;
1249 }
1250
1251 reset(ctx);
1252 --mdpBatchSize;
1253 ++fbBatchSize;
1254 }
1255
1256 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001257}
1258
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001259bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301260 if(mDpy or isSecurePresent(ctx, mDpy) or
1261 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001262 return false;
1263 }
1264 return true;
1265}
1266
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001267bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1268 hwc_display_contents_1_t* list){
1269 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1270 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001271 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001272 return false;
1273 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001274 if(ctx->listStats[mDpy].secureUI)
1275 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001276 return true;
1277}
1278
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001279bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1280 hwc_display_contents_1_t* list) {
1281 const bool secureOnly = true;
1282 return videoOnlyComp(ctx, list, not secureOnly) or
1283 videoOnlyComp(ctx, list, secureOnly);
1284}
1285
1286bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001287 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001288 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1289 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001290 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001291
Saurabh Shahaa236822013-04-24 18:07:26 -07001292 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001293 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001294 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001295 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001296
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001297 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1298 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001299 return false;
1300 }
1301
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001302 /* Bail out if we are processing only secured video layers
1303 * and we dont have any */
1304 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001305 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001306 return false;
1307 }
1308
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001309 if(mCurrentFrame.fbCount)
1310 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001311
Raj Kamal389d6e32014-08-04 14:43:24 +05301312 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001313 adjustForSourceSplit(ctx, list);
1314 }
1315
1316 if(!postHeuristicsHandling(ctx, list)) {
1317 ALOGD_IF(isDebug(), "post heuristic handling failed");
1318 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001319 return false;
1320 }
1321
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001322 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1323 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001324 return true;
1325}
1326
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001327/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1328bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1329 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001330 // Fall back to video only composition, if AIV video mode is enabled
1331 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001332 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1333 __FUNCTION__, mDpy);
1334 return false;
1335 }
1336
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001337 const bool secureOnly = true;
1338 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1339 mdpOnlyLayersComp(ctx, list, secureOnly);
1340
1341}
1342
1343bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1344 hwc_display_contents_1_t* list, bool secureOnly) {
1345
1346 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1347 return false;
1348
1349 /* Bail out if we are processing only secured video layers
1350 * and we dont have any */
1351 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1352 reset(ctx);
1353 return false;
1354 }
1355
1356 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1357 mCurrentFrame.reset(numAppLayers);
1358 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1359
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001360 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001361 /* mark secure RGB layers for MDP comp */
1362 updateSecureRGB(ctx, list);
1363
1364 if(mCurrentFrame.mdpCount == 0) {
1365 reset(ctx);
1366 return false;
1367 }
1368
1369 /* find the maximum batch of layers to be marked for framebuffer */
1370 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1371 if(!ret) {
1372 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1373 reset(ctx);
1374 return false;
1375 }
1376
1377 if(sEnableYUVsplit){
1378 adjustForSourceSplit(ctx, list);
1379 }
1380
1381 if(!postHeuristicsHandling(ctx, list)) {
1382 ALOGD_IF(isDebug(), "post heuristic handling failed");
1383 reset(ctx);
1384 return false;
1385 }
1386
1387 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1388 __FUNCTION__);
1389 return true;
1390}
1391
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001392/* Checks for conditions where YUV layers cannot be bypassed */
1393bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001394 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001395 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001396 return false;
1397 }
1398
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001399 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001400 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1401 return false;
1402 }
1403
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001404 if(isSecuring(ctx, layer)) {
1405 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1406 return false;
1407 }
1408
Saurabh Shah4fdde762013-04-30 18:47:33 -07001409 if(!isValidDimension(ctx, layer)) {
1410 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1411 __FUNCTION__);
1412 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001413 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001414
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001415 if(layer->planeAlpha < 0xFF) {
1416 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1417 in video only mode",
1418 __FUNCTION__);
1419 return false;
1420 }
1421
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001422 return true;
1423}
1424
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001425/* Checks for conditions where Secure RGB layers cannot be bypassed */
1426bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1427 if(isSkipLayer(layer)) {
1428 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1429 __FUNCTION__, mDpy);
1430 return false;
1431 }
1432
1433 if(isSecuring(ctx, layer)) {
1434 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1435 return false;
1436 }
1437
1438 if(not isSupportedForMDPComp(ctx, layer)) {
1439 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1440 __FUNCTION__);
1441 return false;
1442 }
1443 return true;
1444}
1445
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301446/* starts at fromIndex and check for each layer to find
1447 * if it it has overlapping with any Updating layer above it in zorder
1448 * till the end of the batch. returns true if it finds any intersection */
1449bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1450 int fromIndex, int toIndex) {
1451 for(int i = fromIndex; i < toIndex; i++) {
1452 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1453 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1454 return false;
1455 }
1456 }
1457 }
1458 return true;
1459}
1460
1461/* Checks if given layer at targetLayerIndex has any
1462 * intersection with all the updating layers in beween
1463 * fromIndex and toIndex. Returns true if it finds intersectiion */
1464bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1465 int fromIndex, int toIndex, int targetLayerIndex) {
1466 for(int i = fromIndex; i <= toIndex; i++) {
1467 if(!mCurrentFrame.isFBComposed[i]) {
1468 if(areLayersIntersecting(&list->hwLayers[i],
1469 &list->hwLayers[targetLayerIndex])) {
1470 return true;
1471 }
1472 }
1473 }
1474 return false;
1475}
1476
1477int MDPComp::getBatch(hwc_display_contents_1_t* list,
1478 int& maxBatchStart, int& maxBatchEnd,
1479 int& maxBatchCount) {
1480 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301481 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001482 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301483 while (i < mCurrentFrame.layerCount) {
1484 int batchCount = 0;
1485 int batchStart = i;
1486 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001487 /* Adjust batch Z order with the dropped layers so far */
1488 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301489 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301490 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301491 while(i < mCurrentFrame.layerCount) {
1492 if(!mCurrentFrame.isFBComposed[i]) {
1493 if(!batchCount) {
1494 i++;
1495 break;
1496 }
1497 updatingLayersAbove++;
1498 i++;
1499 continue;
1500 } else {
1501 if(mCurrentFrame.drop[i]) {
1502 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001503 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301504 continue;
1505 } else if(updatingLayersAbove <= 0) {
1506 batchCount++;
1507 batchEnd = i;
1508 i++;
1509 continue;
1510 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1511
1512 // We have a valid updating layer already. If layer-i not
1513 // have overlapping with all updating layers in between
1514 // batch-start and i, then we can add layer i to batch.
1515 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1516 batchCount++;
1517 batchEnd = i;
1518 i++;
1519 continue;
1520 } else if(canPushBatchToTop(list, batchStart, i)) {
1521 //If All the non-updating layers with in this batch
1522 //does not have intersection with the updating layers
1523 //above in z-order, then we can safely move the batch to
1524 //higher z-order. Increment fbZ as it is moving up.
1525 if( firstZReverseIndex < 0) {
1526 firstZReverseIndex = i;
1527 }
1528 batchCount++;
1529 batchEnd = i;
1530 fbZ += updatingLayersAbove;
1531 i++;
1532 updatingLayersAbove = 0;
1533 continue;
1534 } else {
1535 //both failed.start the loop again from here.
1536 if(firstZReverseIndex >= 0) {
1537 i = firstZReverseIndex;
1538 }
1539 break;
1540 }
1541 }
1542 }
1543 }
1544 if(batchCount > maxBatchCount) {
1545 maxBatchCount = batchCount;
1546 maxBatchStart = batchStart;
1547 maxBatchEnd = batchEnd;
1548 fbZOrder = fbZ;
1549 }
1550 }
1551 return fbZOrder;
1552}
1553
1554bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1555 hwc_display_contents_1_t* list) {
1556 /* Idea is to keep as many non-updating(cached) layers in FB and
1557 * send rest of them through MDP. This is done in 2 steps.
1558 * 1. Find the maximum contiguous batch of non-updating layers.
1559 * 2. See if we can improve this batch size for caching by adding
1560 * opaque layers around the batch, if they don't have
1561 * any overlapping with the updating layers in between.
1562 * NEVER mark an updating layer for caching.
1563 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001564
1565 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001566 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001567 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301568 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001569
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001570 /* Nothing is cached. No batching needed */
1571 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001572 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001573 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001574
1575 /* No MDP comp layers, try to use other comp modes */
1576 if(mCurrentFrame.mdpCount == 0) {
1577 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001578 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001579
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001581
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301582 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001583 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001584 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001585 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301586 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001587 if(!mCurrentFrame.drop[i]){
1588 //If an unsupported layer is being attempted to
1589 //be pulled out we should fail
1590 if(not isSupportedForMDPComp(ctx, layer)) {
1591 return false;
1592 }
1593 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001594 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001595 }
1596 }
1597
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301598 // update the frame data
1599 mCurrentFrame.fbZ = fbZ;
1600 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001601 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001602 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001603
1604 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301605 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001606
1607 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001609
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001611 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001613 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001614
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001615 for(int i = 0; i < numAppLayers; i++) {
1616 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001617 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001618 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001619 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001620 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001621 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001622 }
1623 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001624
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001625 frame.fbCount = fbCount;
1626 frame.mdpCount = frame.layerCount - frame.fbCount
1627 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001628
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001629 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1630 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001631}
1632
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001633// drop other non-AIV layers from external display list.
1634void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001635 hwc_display_contents_1_t* list) {
1636 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1637 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001638 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001639 mCurrentFrame.dropCount++;
1640 mCurrentFrame.drop[i] = true;
1641 }
1642 }
1643 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1644 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1645 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1646 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1647 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1648 mCurrentFrame.dropCount);
1649}
1650
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001651void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001652 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001653 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1654 for(int index = 0;index < nYuvCount; index++){
1655 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1656 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1657
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001658 if(mCurrentFrame.drop[nYuvIndex]) {
1659 continue;
1660 }
1661
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001663 if(!frame.isFBComposed[nYuvIndex]) {
1664 frame.isFBComposed[nYuvIndex] = true;
1665 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666 }
1667 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001668 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001669 private_handle_t *hnd = (private_handle_t *)layer->handle;
1670 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001671 frame.isFBComposed[nYuvIndex] = false;
1672 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001673 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001674 }
1675 }
1676 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001677
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001678 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1679 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001680}
1681
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001682void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1683 hwc_display_contents_1_t* list) {
1684 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1685 for(int index = 0;index < nSecureRGBCount; index++){
1686 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1687 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1688
1689 if(!isSecureRGBDoable(ctx, layer)) {
1690 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1691 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1692 mCurrentFrame.fbCount++;
1693 }
1694 } else {
1695 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1696 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1697 mCurrentFrame.fbCount--;
1698 }
1699 }
1700 }
1701
1702 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1703 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1704 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1705 mCurrentFrame.fbCount);
1706}
1707
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001708hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1709 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001710 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001711
1712 /* Update only the region of FB needed for composition */
1713 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1714 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1715 hwc_layer_1_t* layer = &list->hwLayers[i];
1716 hwc_rect_t dst = layer->displayFrame;
1717 fbRect = getUnion(fbRect, dst);
1718 }
1719 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001720 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001721 return fbRect;
1722}
1723
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001724bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1725 hwc_display_contents_1_t* list) {
1726
1727 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001728 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001729 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1730 return false;
1731 }
1732
1733 //Limitations checks
1734 if(!hwLimitationsCheck(ctx, list)) {
1735 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1736 return false;
1737 }
1738
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001739 //Configure framebuffer first if applicable
1740 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001741 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001742 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1743 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001744 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1745 __FUNCTION__);
1746 return false;
1747 }
1748 }
1749
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001750 mCurrentFrame.map();
1751
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001752 if(!allocLayerPipes(ctx, list)) {
1753 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001754 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001755 }
1756
1757 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001758 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001759 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001760 int mdpIndex = mCurrentFrame.layerToMDP[index];
1761 hwc_layer_1_t* layer = &list->hwLayers[index];
1762
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301763 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1764 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1765 mdpNextZOrder++;
1766 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001767 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1768 cur_pipe->zOrder = mdpNextZOrder++;
1769
radhakrishnac9a67412013-09-25 17:40:42 +05301770 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301771 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301772 if(configure4k2kYuv(ctx, layer,
1773 mCurrentFrame.mdpToLayer[mdpIndex])
1774 != 0 ){
1775 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1776 for layer %d",__FUNCTION__, index);
1777 return false;
1778 }
1779 else{
1780 mdpNextZOrder++;
1781 }
1782 continue;
1783 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001784 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1785 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301786 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001787 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001789 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001790 }
1791
Saurabh Shaha36be922013-12-16 18:18:39 -08001792 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1793 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1794 ,__FUNCTION__, mDpy);
1795 return false;
1796 }
1797
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001798 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001799 return true;
1800}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001801
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001802bool MDPComp::resourceCheck(hwc_context_t* ctx,
1803 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001804 const bool fbUsed = mCurrentFrame.fbCount;
1805 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1806 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1807 return false;
1808 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001809
1810 //Will benefit cases where a video has non-updating background.
1811 if((mDpy > HWC_DISPLAY_PRIMARY) and
1812 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1813 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1814 return false;
1815 }
1816
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001817 // Init rotCount to number of rotate sessions used by other displays
1818 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1819 // Count the number of rotator sessions required for current display
1820 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1821 if(!mCurrentFrame.isFBComposed[index]) {
1822 hwc_layer_1_t* layer = &list->hwLayers[index];
1823 private_handle_t *hnd = (private_handle_t *)layer->handle;
1824 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1825 rotCount++;
1826 }
1827 }
1828 }
1829 // if number of layers to rotate exceeds max rotator sessions, bail out.
1830 if(rotCount > RotMgr::MAX_ROT_SESS) {
1831 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1832 __FUNCTION__, mDpy);
1833 return false;
1834 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001835 return true;
1836}
1837
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301838bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1839 hwc_display_contents_1_t* list) {
1840
1841 //A-family hw limitation:
1842 //If a layer need alpha scaling, MDP can not support.
1843 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1844 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1845 if(!mCurrentFrame.isFBComposed[i] &&
1846 isAlphaScaled( &list->hwLayers[i])) {
1847 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1848 return false;
1849 }
1850 }
1851 }
1852
1853 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1854 //If multiple layers requires downscaling and also they are overlapping
1855 //fall back to GPU since MDSS can not handle it.
1856 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1857 qdutils::MDPVersion::getInstance().is8x26()) {
1858 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1859 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1860 if(!mCurrentFrame.isFBComposed[i] &&
1861 isDownscaleRequired(botLayer)) {
1862 //if layer-i is marked for MDP and needs downscaling
1863 //check if any MDP layer on top of i & overlaps with layer-i
1864 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1865 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1866 if(!mCurrentFrame.isFBComposed[j] &&
1867 isDownscaleRequired(topLayer)) {
1868 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1869 topLayer->displayFrame);
1870 if(isValidRect(r))
1871 return false;
1872 }
1873 }
1874 }
1875 }
1876 }
1877 return true;
1878}
1879
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001880int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001881 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001882 char property[PROPERTY_VALUE_MAX];
1883
Raj Kamal4393eaa2014-06-06 13:45:20 +05301884 if(!ctx || !list) {
1885 ALOGE("%s: Invalid context or list",__FUNCTION__);
1886 mCachedFrame.reset();
1887 return -1;
1888 }
1889
1890 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001891 if(mDpy == HWC_DISPLAY_PRIMARY) {
1892 sSimulationFlags = 0;
1893 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1894 int currentFlags = atoi(property);
1895 if(currentFlags != sSimulationFlags) {
1896 sSimulationFlags = currentFlags;
1897 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1898 sSimulationFlags, sSimulationFlags);
1899 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001900 }
1901 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001902 // reset PTOR
1903 if(!mDpy)
1904 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001905
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301906 //Do not cache the information for next draw cycle.
1907 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1908 ALOGI("%s: Unsupported layer count for mdp composition",
1909 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001910 mCachedFrame.reset();
1911 return -1;
1912 }
1913
Saurabh Shahb39f8152013-08-22 10:21:44 -07001914 //reset old data
1915 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001916 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1917 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301918
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001919 // Detect the start of animation and fall back to GPU only once to cache
1920 // all the layers in FB and display FB content untill animation completes.
1921 if(ctx->listStats[mDpy].isDisplayAnimating) {
1922 mCurrentFrame.needsRedraw = false;
1923 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1924 mCurrentFrame.needsRedraw = true;
1925 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1926 }
1927 setMDPCompLayerFlags(ctx, list);
1928 mCachedFrame.updateCounts(mCurrentFrame);
1929 ret = -1;
1930 return ret;
1931 } else {
1932 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1933 }
1934
Saurabh Shahb39f8152013-08-22 10:21:44 -07001935 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001936 if(isFrameDoable(ctx)) {
1937 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001938 // if AIV Video mode is enabled, drop all non AIV layers from the
1939 // external display list.
1940 if(ctx->listStats[mDpy].mAIVVideoMode) {
1941 dropNonAIVLayers(ctx, list);
1942 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001943
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001944 // if tryFullFrame fails, try to push all video and secure RGB layers
1945 // to MDP for composition.
1946 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001947 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301948 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001949 setMDPCompLayerFlags(ctx, list);
1950 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001951 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001952 reset(ctx);
1953 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1954 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001955 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001956 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1957 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001958 }
1959 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301960 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1961 enablePartialUpdateForMDP3) {
1962 generateROI(ctx, list);
1963 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1964 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1965 }
1966 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001967 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1968 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001969 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001970 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001971
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001972 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001973 ALOGD("GEOMETRY change: %d",
1974 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001975 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001976 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001977 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001978 }
1979
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001980#ifdef DYNAMIC_FPS
1981 //For primary display, set the dynamic refreshrate
Raj Kamal0d53fc62014-11-25 17:36:36 +05301982 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1983 ctx->mUseMetaDataRefreshRate) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001984 FrameInfo frame;
1985 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301986 memset(&frame.drop, 0, sizeof(frame.drop));
1987 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001988 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1989 __FUNCTION__);
1990 updateLayerCache(ctx, list, frame);
1991 updateYUV(ctx, list, false /*secure only*/, frame);
1992 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1993 //Set the new fresh rate, if there is only one updating YUV layer
1994 //or there is one single RGB layer with this request
1995 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1996 (frame.layerCount == 1)) {
1997 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1998 }
1999 setRefreshRate(ctx, mDpy, refreshRate);
2000 }
2001#endif
2002
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002003 mCachedFrame.cacheAll(list);
2004 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002005 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002006}
2007
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002008bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302009
2010 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302011 int mdpIndex = mCurrentFrame.layerToMDP[index];
2012 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2013 info.pipeInfo = new MdpYUVPipeInfo;
2014 info.rot = NULL;
2015 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302016
2017 pipe_info.lIndex = ovutils::OV_INVALID;
2018 pipe_info.rIndex = ovutils::OV_INVALID;
2019
Saurabh Shahc62f3982014-03-05 14:28:26 -08002020 Overlay::PipeSpecs pipeSpecs;
2021 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2022 pipeSpecs.needsScaling = true;
2023 pipeSpecs.dpy = mDpy;
2024 pipeSpecs.fb = false;
2025
2026 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302027 if(pipe_info.lIndex == ovutils::OV_INVALID){
2028 bRet = false;
2029 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2030 __FUNCTION__);
2031 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002032 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302033 if(pipe_info.rIndex == ovutils::OV_INVALID){
2034 bRet = false;
2035 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2036 __FUNCTION__);
2037 }
2038 return bRet;
2039}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002040
2041int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2042 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002043 if (ctx->mPtorInfo.isActive()) {
2044 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002045 if (fd < 0) {
2046 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002047 }
2048 }
2049 return fd;
2050}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002051//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002052
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002053void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302054 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002055 //If 4k2k Yuv layer split is possible, and if
2056 //fbz is above 4k2k layer, increment fb zorder by 1
2057 //as we split 4k2k layer and increment zorder for right half
2058 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002059 if(!ctx)
2060 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002061 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302062 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2063 index++) {
2064 if(!mCurrentFrame.isFBComposed[index]) {
2065 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2066 mdpNextZOrder++;
2067 }
2068 mdpNextZOrder++;
2069 hwc_layer_1_t* layer = &list->hwLayers[index];
2070 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302071 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302072 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2073 mCurrentFrame.fbZ += 1;
2074 mdpNextZOrder++;
2075 //As we split 4kx2k yuv layer and program to 2 VG pipes
2076 //(if available) increase mdpcount by 1.
2077 mCurrentFrame.mdpCount++;
2078 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002079 }
2080 }
2081 }
radhakrishnac9a67412013-09-25 17:40:42 +05302082}
2083
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002084/*
2085 * Configures pipe(s) for MDP composition
2086 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002087int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002088 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002089 MdpPipeInfoNonSplit& mdp_info =
2090 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302091 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002092 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002093 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002094
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002095 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2096 __FUNCTION__, layer, zOrder, dest);
2097
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002098 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002099 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002100}
2101
Saurabh Shah88e4d272013-09-03 13:31:29 -07002102bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002103 hwc_display_contents_1_t* list) {
2104 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002105
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002106 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002107
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002108 hwc_layer_1_t* layer = &list->hwLayers[index];
2109 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302110 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002111 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302112 continue;
2113 }
2114 }
2115
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002116 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002117 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002118 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002119 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002120 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002121
Saurabh Shahc62f3982014-03-05 14:28:26 -08002122 Overlay::PipeSpecs pipeSpecs;
2123 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2124 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2125 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2126 (qdutils::MDPVersion::getInstance().is8x26() and
2127 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2128 pipeSpecs.dpy = mDpy;
2129 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002130 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002131
Saurabh Shahc62f3982014-03-05 14:28:26 -08002132 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2133
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002134 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002135 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002136 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137 }
2138 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002139 return true;
2140}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002141
radhakrishnac9a67412013-09-25 17:40:42 +05302142int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2143 PipeLayerPair& PipeLayerPair) {
2144 MdpYUVPipeInfo& mdp_info =
2145 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2146 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302147 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302148 eDest lDest = mdp_info.lIndex;
2149 eDest rDest = mdp_info.rIndex;
2150
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002151 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302152 lDest, rDest, &PipeLayerPair.rot);
2153}
2154
Saurabh Shah88e4d272013-09-03 13:31:29 -07002155bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002156
Raj Kamal4393eaa2014-06-06 13:45:20 +05302157 if(!isEnabled() or !mModeOn) {
2158 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302159 return true;
2160 }
2161
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002162 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002163 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002164 sHandleTimeout = true;
2165 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002166
2167 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002168 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002169
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002170 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2171 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002172 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002173 if(mCurrentFrame.isFBComposed[i]) continue;
2174
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002175 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002176 private_handle_t *hnd = (private_handle_t *)layer->handle;
2177 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002178 if (!(layer->flags & HWC_COLOR_FILL)) {
2179 ALOGE("%s handle null", __FUNCTION__);
2180 return false;
2181 }
2182 // No PLAY for Color layer
2183 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2184 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002185 }
2186
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002187 int mdpIndex = mCurrentFrame.layerToMDP[i];
2188
Raj Kamal389d6e32014-08-04 14:43:24 +05302189 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302190 {
2191 MdpYUVPipeInfo& pipe_info =
2192 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2193 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2194 ovutils::eDest indexL = pipe_info.lIndex;
2195 ovutils::eDest indexR = pipe_info.rIndex;
2196 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302197 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302198 if(rot) {
2199 rot->queueBuffer(fd, offset);
2200 fd = rot->getDstMemId();
2201 offset = rot->getDstOffset();
2202 }
2203 if(indexL != ovutils::OV_INVALID) {
2204 ovutils::eDest destL = (ovutils::eDest)indexL;
2205 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2206 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2207 if (!ov.queueBuffer(fd, offset, destL)) {
2208 ALOGE("%s: queueBuffer failed for display:%d",
2209 __FUNCTION__, mDpy);
2210 return false;
2211 }
2212 }
2213
2214 if(indexR != ovutils::OV_INVALID) {
2215 ovutils::eDest destR = (ovutils::eDest)indexR;
2216 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2217 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2218 if (!ov.queueBuffer(fd, offset, destR)) {
2219 ALOGE("%s: queueBuffer failed for display:%d",
2220 __FUNCTION__, mDpy);
2221 return false;
2222 }
2223 }
2224 }
2225 else{
2226 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002227 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302228 ovutils::eDest dest = pipe_info.index;
2229 if(dest == ovutils::OV_INVALID) {
2230 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002231 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302232 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002233
radhakrishnac9a67412013-09-25 17:40:42 +05302234 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2235 continue;
2236 }
2237
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002238 int fd = hnd->fd;
2239 uint32_t offset = (uint32_t)hnd->offset;
2240 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2241 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002242 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002243 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002244 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002245 }
2246
radhakrishnac9a67412013-09-25 17:40:42 +05302247 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2248 using pipe: %d", __FUNCTION__, layer,
2249 hnd, dest );
2250
radhakrishnac9a67412013-09-25 17:40:42 +05302251 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2252 if(rot) {
2253 if(!rot->queueBuffer(fd, offset))
2254 return false;
2255 fd = rot->getDstMemId();
2256 offset = rot->getDstOffset();
2257 }
2258
2259 if (!ov.queueBuffer(fd, offset, dest)) {
2260 ALOGE("%s: queueBuffer failed for display:%d ",
2261 __FUNCTION__, mDpy);
2262 return false;
2263 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002264 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002265
2266 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002267 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002268 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002269}
2270
Saurabh Shah88e4d272013-09-03 13:31:29 -07002271//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002272
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002273void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302274 hwc_display_contents_1_t* list){
2275 //if 4kx2k yuv layer is totally present in either in left half
2276 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302277 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302278 if(mCurrentFrame.fbZ >= 0) {
2279 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2280 index++) {
2281 if(!mCurrentFrame.isFBComposed[index]) {
2282 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2283 mdpNextZOrder++;
2284 }
2285 mdpNextZOrder++;
2286 hwc_layer_1_t* layer = &list->hwLayers[index];
2287 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302288 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302289 hwc_rect_t dst = layer->displayFrame;
2290 if((dst.left > lSplit) || (dst.right < lSplit)) {
2291 mCurrentFrame.mdpCount += 1;
2292 }
2293 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2294 mCurrentFrame.fbZ += 1;
2295 mdpNextZOrder++;
2296 }
2297 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002298 }
radhakrishnac9a67412013-09-25 17:40:42 +05302299 }
2300}
2301
Saurabh Shah88e4d272013-09-03 13:31:29 -07002302bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002303 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002304
Saurabh Shahc62f3982014-03-05 14:28:26 -08002305 const int lSplit = getLeftSplit(ctx, mDpy);
2306 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002307 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002308 pipe_info.lIndex = ovutils::OV_INVALID;
2309 pipe_info.rIndex = ovutils::OV_INVALID;
2310
Saurabh Shahc62f3982014-03-05 14:28:26 -08002311 Overlay::PipeSpecs pipeSpecs;
2312 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2313 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2314 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2315 pipeSpecs.dpy = mDpy;
2316 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2317 pipeSpecs.fb = false;
2318
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002319 // Acquire pipe only for the updating half
2320 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2321 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2322
2323 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002324 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002325 if(pipe_info.lIndex == ovutils::OV_INVALID)
2326 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002327 }
2328
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002329 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002330 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2331 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002332 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002333 return false;
2334 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002335
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002336 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002337}
2338
Saurabh Shah88e4d272013-09-03 13:31:29 -07002339bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002340 hwc_display_contents_1_t* list) {
2341 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002342
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002343 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002344
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002345 hwc_layer_1_t* layer = &list->hwLayers[index];
2346 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302347 hwc_rect_t dst = layer->displayFrame;
2348 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302349 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302350 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002351 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302352 continue;
2353 }
2354 }
2355 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002356 int mdpIndex = mCurrentFrame.layerToMDP[index];
2357 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002358 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002359 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002360 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002361
Saurabh Shahc62f3982014-03-05 14:28:26 -08002362 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2363 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2364 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002365 return false;
2366 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002367 }
2368 return true;
2369}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002370
radhakrishnac9a67412013-09-25 17:40:42 +05302371int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2372 PipeLayerPair& PipeLayerPair) {
2373 const int lSplit = getLeftSplit(ctx, mDpy);
2374 hwc_rect_t dst = layer->displayFrame;
2375 if((dst.left > lSplit)||(dst.right < lSplit)){
2376 MdpYUVPipeInfo& mdp_info =
2377 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2378 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302379 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302380 eDest lDest = mdp_info.lIndex;
2381 eDest rDest = mdp_info.rIndex;
2382
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002383 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302384 lDest, rDest, &PipeLayerPair.rot);
2385 }
2386 else{
2387 return configure(ctx, layer, PipeLayerPair);
2388 }
2389}
2390
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002391/*
2392 * Configures pipe(s) for MDP composition
2393 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002394int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002395 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002396 MdpPipeInfoSplit& mdp_info =
2397 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002398 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302399 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002400 eDest lDest = mdp_info.lIndex;
2401 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002402
2403 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2404 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2405
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002406 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002407 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002408}
2409
Saurabh Shah88e4d272013-09-03 13:31:29 -07002410bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002411
Raj Kamal4393eaa2014-06-06 13:45:20 +05302412 if(!isEnabled() or !mModeOn) {
2413 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302414 return true;
2415 }
2416
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002417 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002418 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002419 sHandleTimeout = true;
2420 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002421
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002422 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002423 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002424
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002425 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2426 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002427 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002428 if(mCurrentFrame.isFBComposed[i]) continue;
2429
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002430 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002431 private_handle_t *hnd = (private_handle_t *)layer->handle;
2432 if(!hnd) {
2433 ALOGE("%s handle null", __FUNCTION__);
2434 return false;
2435 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002436
2437 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2438 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002439 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002440
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002441 int mdpIndex = mCurrentFrame.layerToMDP[i];
2442
Raj Kamal389d6e32014-08-04 14:43:24 +05302443 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302444 {
2445 MdpYUVPipeInfo& pipe_info =
2446 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2447 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2448 ovutils::eDest indexL = pipe_info.lIndex;
2449 ovutils::eDest indexR = pipe_info.rIndex;
2450 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302451 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302452 if(rot) {
2453 rot->queueBuffer(fd, offset);
2454 fd = rot->getDstMemId();
2455 offset = rot->getDstOffset();
2456 }
2457 if(indexL != ovutils::OV_INVALID) {
2458 ovutils::eDest destL = (ovutils::eDest)indexL;
2459 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2460 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2461 if (!ov.queueBuffer(fd, offset, destL)) {
2462 ALOGE("%s: queueBuffer failed for display:%d",
2463 __FUNCTION__, mDpy);
2464 return false;
2465 }
2466 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002467
radhakrishnac9a67412013-09-25 17:40:42 +05302468 if(indexR != ovutils::OV_INVALID) {
2469 ovutils::eDest destR = (ovutils::eDest)indexR;
2470 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2471 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2472 if (!ov.queueBuffer(fd, offset, destR)) {
2473 ALOGE("%s: queueBuffer failed for display:%d",
2474 __FUNCTION__, mDpy);
2475 return false;
2476 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002477 }
2478 }
radhakrishnac9a67412013-09-25 17:40:42 +05302479 else{
2480 MdpPipeInfoSplit& pipe_info =
2481 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2482 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002483
radhakrishnac9a67412013-09-25 17:40:42 +05302484 ovutils::eDest indexL = pipe_info.lIndex;
2485 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002486
radhakrishnac9a67412013-09-25 17:40:42 +05302487 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002488 uint32_t offset = (uint32_t)hnd->offset;
2489 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2490 if (!mDpy && (index != -1)) {
2491 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2492 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002493 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002494 }
radhakrishnac9a67412013-09-25 17:40:42 +05302495
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002496 if(ctx->mAD->draw(ctx, fd, offset)) {
2497 fd = ctx->mAD->getDstFd();
2498 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002499 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002500
radhakrishnac9a67412013-09-25 17:40:42 +05302501 if(rot) {
2502 rot->queueBuffer(fd, offset);
2503 fd = rot->getDstMemId();
2504 offset = rot->getDstOffset();
2505 }
2506
2507 //************* play left mixer **********
2508 if(indexL != ovutils::OV_INVALID) {
2509 ovutils::eDest destL = (ovutils::eDest)indexL;
2510 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2511 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2512 if (!ov.queueBuffer(fd, offset, destL)) {
2513 ALOGE("%s: queueBuffer failed for left mixer",
2514 __FUNCTION__);
2515 return false;
2516 }
2517 }
2518
2519 //************* play right mixer **********
2520 if(indexR != ovutils::OV_INVALID) {
2521 ovutils::eDest destR = (ovutils::eDest)indexR;
2522 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2523 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2524 if (!ov.queueBuffer(fd, offset, destR)) {
2525 ALOGE("%s: queueBuffer failed for right mixer",
2526 __FUNCTION__);
2527 return false;
2528 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002529 }
2530 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002531
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002532 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2533 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002534
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002535 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002536}
Saurabh Shahab47c692014-02-12 18:45:57 -08002537
2538//================MDPCompSrcSplit==============================================
2539bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002540 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002541 private_handle_t *hnd = (private_handle_t *)layer->handle;
2542 hwc_rect_t dst = layer->displayFrame;
2543 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2544 pipe_info.lIndex = ovutils::OV_INVALID;
2545 pipe_info.rIndex = ovutils::OV_INVALID;
2546
2547 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2548 //should have a higher priority than the right one. Pipe priorities are
2549 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002550
Saurabh Shahc62f3982014-03-05 14:28:26 -08002551 Overlay::PipeSpecs pipeSpecs;
2552 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2553 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2554 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2555 pipeSpecs.dpy = mDpy;
2556 pipeSpecs.fb = false;
2557
Saurabh Shahab47c692014-02-12 18:45:57 -08002558 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002559 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002560 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002561 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002562 }
2563
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002564 /* Use 2 pipes IF
2565 a) Layer's crop width is > 2048 or
2566 b) Layer's dest width > 2048 or
2567 c) On primary, driver has indicated with caps to split always. This is
2568 based on an empirically derived value of panel height. Applied only
2569 if the layer's width is > mixer's width
2570 */
2571
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302572 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002573 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302574 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002575 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2576 const uint32_t dstWidth = dst.right - dst.left;
2577 const uint32_t dstHeight = dst.bottom - dst.top;
2578 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002579 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002580 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2581 crop.bottom - crop.top;
2582 //Approximation to actual clock, ignoring the common factors in pipe and
2583 //mixer cases like line_time
2584 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2585 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002586
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002587 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2588 //pipe line length, we are still using 2 pipes. This is fine just because
2589 //this is source split where destination doesn't matter. Evaluate later to
2590 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002591 if(dstWidth > mdpHw.getMaxMixerWidth() or
2592 cropWidth > mdpHw.getMaxMixerWidth() or
2593 (primarySplitAlways and
2594 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002595 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002596 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002597 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002598 }
2599
2600 // Return values
2601 // 1 Left pipe is higher priority, do nothing.
2602 // 0 Pipes of same priority.
2603 //-1 Right pipe is of higher priority, needs swap.
2604 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2605 pipe_info.rIndex) == -1) {
2606 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002607 }
2608 }
2609
2610 return true;
2611}
2612
Saurabh Shahab47c692014-02-12 18:45:57 -08002613int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2614 PipeLayerPair& PipeLayerPair) {
2615 private_handle_t *hnd = (private_handle_t *)layer->handle;
2616 if(!hnd) {
2617 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2618 return -1;
2619 }
2620 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2621 MdpPipeInfoSplit& mdp_info =
2622 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2623 Rotator **rot = &PipeLayerPair.rot;
2624 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002625 eDest lDest = mdp_info.lIndex;
2626 eDest rDest = mdp_info.rIndex;
2627 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2628 hwc_rect_t dst = layer->displayFrame;
2629 int transform = layer->transform;
2630 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002631 int rotFlags = ROT_FLAGS_NONE;
2632 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2633 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2634
2635 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2636 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2637
2638 // Handle R/B swap
2639 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2640 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2641 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2642 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2643 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2644 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002645 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002646 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2647 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002648 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002649 /* Calculate the external display position based on MDP downscale,
2650 ActionSafe, and extorientation features. */
2651 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002652
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002653 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302654 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002655 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002656
2657 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2658 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002659 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002660 }
2661
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002662 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002663 (*rot) = ctx->mRotMgr->getNext();
2664 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002665 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002666 //If the video is using a single pipe, enable BWC
2667 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002668 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2669 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002670 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002671 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002672 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002673 ALOGE("%s: configRotator failed!", __FUNCTION__);
2674 return -1;
2675 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002676 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002677 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002678 }
2679
2680 //If 2 pipes being used, divide layer into half, crop and dst
2681 hwc_rect_t cropL = crop;
2682 hwc_rect_t cropR = crop;
2683 hwc_rect_t dstL = dst;
2684 hwc_rect_t dstR = dst;
2685 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2686 cropL.right = (crop.right + crop.left) / 2;
2687 cropR.left = cropL.right;
2688 sanitizeSourceCrop(cropL, cropR, hnd);
2689
Saurabh Shahb729b192014-08-15 18:04:24 -07002690 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002691 //Swap crops on H flip since 2 pipes are being used
2692 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2693 hwc_rect_t tmp = cropL;
2694 cropL = cropR;
2695 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002696 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002697 }
2698
Saurabh Shahb729b192014-08-15 18:04:24 -07002699 //cropSwap trick: If the src and dst widths are both odd, let us say
2700 //2507, then splitting both into half would cause left width to be 1253
2701 //and right 1254. If crop is swapped because of H flip, this will cause
2702 //left crop width to be 1254, whereas left dst width remains 1253, thus
2703 //inducing a scaling that is unaccounted for. To overcome that we add 1
2704 //to the dst width if there is a cropSwap. So if the original width was
2705 //2507, the left dst width will be 1254. Even if the original width was
2706 //even for ex: 2508, the left dst width will still remain 1254.
2707 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002708 dstR.left = dstL.right;
2709 }
2710
2711 //For the mdp, since either we are pre-rotating or MDP does flips
2712 orient = OVERLAY_TRANSFORM_0;
2713 transform = 0;
2714
2715 //configure left pipe
2716 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002717 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002718 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2719 (ovutils::eBlending) getBlending(layer->blending));
2720
2721 if(configMdp(ctx->mOverlay, pargL, orient,
2722 cropL, dstL, metadata, lDest) < 0) {
2723 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2724 return -1;
2725 }
2726 }
2727
2728 //configure right pipe
2729 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002730 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002731 static_cast<eRotFlags>(rotFlags),
2732 layer->planeAlpha,
2733 (ovutils::eBlending) getBlending(layer->blending));
2734 if(configMdp(ctx->mOverlay, pargR, orient,
2735 cropR, dstR, metadata, rDest) < 0) {
2736 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2737 return -1;
2738 }
2739 }
2740
2741 return 0;
2742}
2743
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002744bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2745 Locker::Autolock _l(ctx->mDrawLock);
2746 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2747 char path[MAX_SYSFS_FILE_PATH];
2748 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2749 int fd = open(path, O_RDONLY);
2750 if(fd < 0) {
2751 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2752 return -1;
2753 }
2754 char value[4];
2755 ssize_t size_read = read(fd, value, sizeof(value)-1);
2756 if(size_read <= 0) {
2757 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2758 close(fd);
2759 return -1;
2760 }
2761 close(fd);
2762 value[size_read] = '\0';
2763 return atoi(value);
2764}
2765
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002766int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2767 Locker::Autolock _l(ctx->mDrawLock);
2768 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2769 char path[MAX_SYSFS_FILE_PATH];
2770 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2771 int fd = open(path, O_WRONLY);
2772 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002773 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002774 return -1;
2775 }
2776 char value[4];
2777 snprintf(value, sizeof(value), "%d", (int)enable);
2778 ssize_t ret = write(fd, value, strlen(value));
2779 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002780 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002781 close(fd);
2782 return -1;
2783 }
2784 close(fd);
2785 sIsPartialUpdateActive = enable;
2786 return 0;
2787}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002788}; //namespace
2789