blob: 98cd1f4dbce7e660a5e4b8e9035295d1835583ae [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
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700197 return true;
198}
199
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800200void MDPComp::reset(hwc_context_t *ctx) {
201 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700202 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800203 ctx->mOverlay->clear(mDpy);
204 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700205}
206
Raj Kamal4393eaa2014-06-06 13:45:20 +0530207void MDPComp::reset() {
208 sHandleTimeout = false;
209 mModeOn = false;
210}
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212void MDPComp::timeout_handler(void *udata) {
213 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
214
215 if(!ctx) {
216 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
217 return;
218 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800219 Locker::Autolock _l(ctx->mDrawLock);
220 // Handle timeout event only if the previous composition is MDP or MIXED.
221 if(!sHandleTimeout) {
222 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
223 return;
224 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700225 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700226 ALOGE("%s: HWC proc not registered", __FUNCTION__);
227 return;
228 }
229 sIdleFallBack = true;
230 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700231 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232}
233
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700234void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
235 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
236 uint32_t maxSupported = (int)mdpVersion.getBlendStages() - 2;
237 if(value > maxSupported) {
238 ALOGW("%s: Input exceeds max value supported. Setting to"
239 "max value: %d", __FUNCTION__, maxSupported);
240 }
241 sMaxPipesPerMixer = min(value, maxSupported);
242}
243
Saurabh Shah59562ff2014-09-30 16:13:12 -0700244void MDPComp::setIdleTimeout(const uint32_t& timeout) {
245 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
246
247 if(sIdleInvalidator) {
248 if(timeout <= ONE_REFRESH_PERIOD_MS) {
249 //If the specified timeout is < 1 draw cycle worth, "virtually"
250 //disable idle timeout. The ideal way for clients to disable
251 //timeout is to set it to 0
252 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
253 ALOGI("Disabled idle timeout");
254 return;
255 }
256 sIdleInvalidator->setIdleTimeout(timeout);
257 ALOGI("Idle timeout set to %u", timeout);
258 } else {
259 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
260 }
261}
262
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800263void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264 hwc_display_contents_1_t* list) {
265 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800266
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800267 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800268 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800269 if(!mCurrentFrame.isFBComposed[index]) {
270 layerProp[index].mFlags |= HWC_MDPCOMP;
271 layer->compositionType = HWC_OVERLAY;
272 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800273 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700274 /* Drop the layer when its already present in FB OR when it lies
275 * outside frame's ROI */
276 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800277 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700278 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800279 }
280 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700281}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500282
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800283void MDPComp::setRedraw(hwc_context_t *ctx,
284 hwc_display_contents_1_t* list) {
285 mCurrentFrame.needsRedraw = false;
286 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
287 (list->flags & HWC_GEOMETRY_CHANGED) ||
288 isSkipPresent(ctx, mDpy)) {
289 mCurrentFrame.needsRedraw = true;
290 }
291}
292
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800293MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700294 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700295 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800297
Saurabh Shahaa236822013-04-24 18:07:26 -0700298void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700299 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800300 if(mdpToLayer[i].pipeInfo) {
301 delete mdpToLayer[i].pipeInfo;
302 mdpToLayer[i].pipeInfo = NULL;
303 //We dont own the rotator
304 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800305 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800306 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800307
308 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
309 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700310 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800311
Saurabh Shahaa236822013-04-24 18:07:26 -0700312 layerCount = numLayers;
313 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800314 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700315 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800316 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800317}
318
Saurabh Shahaa236822013-04-24 18:07:26 -0700319void MDPComp::FrameInfo::map() {
320 // populate layer and MDP maps
321 int mdpIdx = 0;
322 for(int idx = 0; idx < layerCount; idx++) {
323 if(!isFBComposed[idx]) {
324 mdpToLayer[mdpIdx].listIndex = idx;
325 layerToMDP[idx] = mdpIdx++;
326 }
327 }
328}
329
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330MDPComp::LayerCache::LayerCache() {
331 reset();
332}
333
334void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700335 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530336 memset(&isFBComposed, true, sizeof(isFBComposed));
337 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800338 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700339}
340
341void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530342 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700343 for(int i = 0; i < numAppLayers; i++) {
344 hnd[i] = list->hwLayers[i].handle;
345 }
346}
347
348void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700349 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530350 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
351 memcpy(&drop, &curFrame.drop, sizeof(drop));
352}
353
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800354bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
355 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530356 if(layerCount != curFrame.layerCount)
357 return false;
358 for(int i = 0; i < curFrame.layerCount; i++) {
359 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
360 (curFrame.drop[i] != drop[i])) {
361 return false;
362 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800363 if(curFrame.isFBComposed[i] &&
364 (hnd[i] != list->hwLayers[i].handle)){
365 return false;
366 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530367 }
368 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800369}
370
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700371bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
372 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800373 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700374 (not isValidDimension(ctx,layer))
375 //More conditions here, SKIP, sRGB+Blend etc
376 ) {
377 return false;
378 }
379 return true;
380}
381
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530382bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800383 private_handle_t *hnd = (private_handle_t *)layer->handle;
384
385 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700386 if (layer->flags & HWC_COLOR_FILL) {
387 // Color layer
388 return true;
389 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700390 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800391 return false;
392 }
393
Naseer Ahmede850a802013-09-06 13:12:52 -0400394 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400395 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400396 return false;
397
Saurabh Shah62e1d732013-09-17 10:44:05 -0700398 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700399 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700400 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700401 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
402 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700403 int dst_w = dst.right - dst.left;
404 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800405 float w_scale = ((float)crop_w / (float)dst_w);
406 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530407 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700408
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800409 /* Workaround for MDP HW limitation in DSI command mode panels where
410 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
411 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530412 * There also is a HW limilation in MDP, minimum block size is 2x2
413 * Fallback to GPU if height is less than 2.
414 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700415 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800416 return false;
417
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800418 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530419 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800420 const float w_dscale = w_scale;
421 const float h_dscale = h_scale;
422
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800423 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700424
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530425 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700426 /* On targets that doesnt support Decimation (eg.,8x26)
427 * maximum downscale support is overlay pipe downscale.
428 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400429 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530430 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700431 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800432 return false;
433 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700434 // Decimation on macrotile format layers is not supported.
435 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530436 /* Bail out if
437 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700438 * 2. exceeds maximum downscale limit
439 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400440 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530441 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700442 w_dscale > maxMDPDownscale ||
443 h_dscale > maxMDPDownscale) {
444 return false;
445 }
446 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800447 return false;
448 }
449 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700450 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700451 return false;
452 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700453 }
454
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800455 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530456 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800457 const float w_uscale = 1.0f / w_scale;
458 const float h_uscale = 1.0f / h_scale;
459
460 if(w_uscale > upscale || h_uscale > upscale)
461 return false;
462 }
463
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800464 return true;
465}
466
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800467bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700468 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800469
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800470 if(!isEnabled()) {
471 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700472 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530473 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530474 qdutils::MDPVersion::getInstance().is8x16() ||
475 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800476 ctx->mVideoTransFlag &&
477 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700478 //1 Padding round to shift pipes across mixers
479 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
480 __FUNCTION__);
481 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700482 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
483 /* TODO: freeing up all the resources only for the targets having total
484 number of pipes < 8. Need to analyze number of VIG pipes used
485 for primary in previous draw cycle and accordingly decide
486 whether to fall back to full GPU comp or video only comp
487 */
488 if(isSecondaryConfiguring(ctx)) {
489 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
490 __FUNCTION__);
491 ret = false;
492 } else if(ctx->isPaddingRound) {
493 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
494 __FUNCTION__,mDpy);
495 ret = false;
496 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800497 } else if (ctx->isDMAStateChanging) {
498 // Bail out if a padding round has been invoked in order to switch DMA
499 // state to block mode. We need this to cater for the case when a layer
500 // requires rotation in the current frame.
501 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
502 __FUNCTION__);
503 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700504 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800505
Saurabh Shahaa236822013-04-24 18:07:26 -0700506 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800507}
508
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800509void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
510 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
511 fbRect = getIntersection(fbRect, roi);
512}
513
514/* 1) Identify layers that are not visible or lying outside the updating ROI and
515 * drop them from composition.
516 * 2) If we have a scaling layer which needs cropping against generated
517 * ROI, reset ROI to full resolution. */
518bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
519 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700520 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800521 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800522
523 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800524 if(!isValidRect(visibleRect)) {
525 mCurrentFrame.drop[i] = true;
526 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800527 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800528 }
529
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700530 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700531 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800532 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700533
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700534 if(!isValidRect(res)) {
535 mCurrentFrame.drop[i] = true;
536 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800537 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700538 /* Reset frame ROI when any layer which needs scaling also needs ROI
539 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800541 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700542 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
543 mCurrentFrame.dropCount = 0;
544 return false;
545 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800546
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800547 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530548 if (layer->blending == HWC_BLENDING_NONE &&
549 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800550 visibleRect = deductRect(visibleRect, res);
551 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700552 }
553 return true;
554}
555
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800556/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
557 * are updating. If DirtyRegion is applicable, calculate it by accounting all
558 * the changing layer's dirtyRegion. */
559void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
560 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700561 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800562 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700563 return;
564
565 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800566 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
567 (int)ctx->dpyAttr[mDpy].yres};
568
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700569 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800570 hwc_layer_1_t* layer = &list->hwLayers[index];
571 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800572 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700573 hwc_rect_t dst = layer->displayFrame;
574 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800576#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700578 {
579 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
580 int x_off = dst.left - src.left;
581 int y_off = dst.top - src.top;
582 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
583 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800584#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800585
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800586 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700587 }
588 }
589
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800590 /* No layer is updating. Still SF wants a refresh.*/
591 if(!isValidRect(roi))
592 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800593
594 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800595 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800596
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800597 ctx->listStats[mDpy].lRoi = roi;
598 if(!validateAndApplyROI(ctx, list))
599 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700600
601 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800602 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
603 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
604}
605
606void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
607 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
608 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
609
610 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
611 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
612 fbRect = getUnion(l_fbRect, r_fbRect);
613}
614/* 1) Identify layers that are not visible or lying outside BOTH the updating
615 * ROI's and drop them from composition. If a layer is spanning across both
616 * the halves of the screen but needed by only ROI, the non-contributing
617 * half will not be programmed for MDP.
618 * 2) If we have a scaling layer which needs cropping against generated
619 * ROI, reset ROI to full resolution. */
620bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
621 hwc_display_contents_1_t* list) {
622
623 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
624
625 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
626 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
627
628 for(int i = numAppLayers - 1; i >= 0; i--){
629 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
630 {
631 mCurrentFrame.drop[i] = true;
632 mCurrentFrame.dropCount++;
633 continue;
634 }
635
636 const hwc_layer_1_t* layer = &list->hwLayers[i];
637 hwc_rect_t dstRect = layer->displayFrame;
638
639 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
640 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
641 hwc_rect_t res = getUnion(l_res, r_res);
642
643 if(!isValidRect(l_res) && !isValidRect(r_res)) {
644 mCurrentFrame.drop[i] = true;
645 mCurrentFrame.dropCount++;
646 } else {
647 /* Reset frame ROI when any layer which needs scaling also needs ROI
648 * cropping */
649 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
650 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
651 mCurrentFrame.dropCount = 0;
652 return false;
653 }
654
radhakrishna4efbdd62014-11-03 13:19:27 +0530655 if (layer->blending == HWC_BLENDING_NONE &&
656 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800657 visibleRectL = deductRect(visibleRectL, l_res);
658 visibleRectR = deductRect(visibleRectR, r_res);
659 }
660 }
661 }
662 return true;
663}
664/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
665 * are updating. If DirtyRegion is applicable, calculate it by accounting all
666 * the changing layer's dirtyRegion. */
667void MDPCompSplit::generateROI(hwc_context_t *ctx,
668 hwc_display_contents_1_t* list) {
669 if(!canPartialUpdate(ctx, list))
670 return;
671
672 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
673 int lSplit = getLeftSplit(ctx, mDpy);
674
675 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
676 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
677
678 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
679 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
680
681 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
682 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
683
684 for(int index = 0; index < numAppLayers; index++ ) {
685 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800686 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800687 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800688 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700689 hwc_rect_t dst = layer->displayFrame;
690 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800691
692#ifdef QCOM_BSP
693 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700694 {
695 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
696 int x_off = dst.left - src.left;
697 int y_off = dst.top - src.top;
698 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
699 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800700#endif
701
702 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
703 if(isValidRect(l_dst))
704 l_roi = getUnion(l_roi, l_dst);
705
706 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
707 if(isValidRect(r_dst))
708 r_roi = getUnion(r_roi, r_dst);
709 }
710 }
711
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700712 /* For panels that cannot accept commands in both the interfaces, we cannot
713 * send two ROI's (for each half). We merge them into single ROI and split
714 * them across lSplit for MDP mixer use. The ROI's will be merged again
715 * finally before udpating the panel in the driver. */
716 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
717 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
718 l_roi = getIntersection(temp_roi, l_frame);
719 r_roi = getIntersection(temp_roi, r_frame);
720 }
721
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800722 /* No layer is updating. Still SF wants a refresh. */
723 if(!isValidRect(l_roi) && !isValidRect(r_roi))
724 return;
725
726 l_roi = getSanitizeROI(l_roi, l_frame);
727 r_roi = getSanitizeROI(r_roi, r_frame);
728
729 ctx->listStats[mDpy].lRoi = l_roi;
730 ctx->listStats[mDpy].rRoi = r_roi;
731
732 if(!validateAndApplyROI(ctx, list))
733 resetROI(ctx, mDpy);
734
735 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
736 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
737 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
738 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
739 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
740 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700741}
742
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800743/* Checks for conditions where all the layers marked for MDP comp cannot be
744 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800745bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800746 hwc_display_contents_1_t* list){
747
Saurabh Shahaa236822013-04-24 18:07:26 -0700748 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800749
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700750 // Fall back to video only composition, if AIV video mode is enabled
751 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700752 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
753 __FUNCTION__, mDpy);
754 return false;
755 }
756
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400757 // No Idle fall back, if secure display or secure RGB layers are present or
758 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700759 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400760 !ctx->listStats[mDpy].secureRGBCount) &&
761 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700762 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
763 return false;
764 }
765
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800766 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700767 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
768 __FUNCTION__,
769 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800770 return false;
771 }
772
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700773 // if secondary is configuring or Padding round, fall back to video only
774 // composition and release all assigned non VIG pipes from primary.
775 if(isSecondaryConfiguring(ctx)) {
776 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
777 __FUNCTION__);
778 return false;
779 } else if(ctx->isPaddingRound) {
780 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
781 __FUNCTION__,mDpy);
782 return false;
783 }
784
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700785 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800786 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700787 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800788 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
789 return false;
790 }
791
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800792 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800793 hwc_layer_1_t* layer = &list->hwLayers[i];
794 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800795
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800796 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700797 if(!canUseRotator(ctx, mDpy)) {
798 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
799 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700800 return false;
801 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800802 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530803
804 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
805 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800806 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700807 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530808 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
809 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
810 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800811 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700812
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700813 if(ctx->mAD->isDoable()) {
814 return false;
815 }
816
Saurabh Shahaa236822013-04-24 18:07:26 -0700817 //If all above hard conditions are met we can do full or partial MDP comp.
818 bool ret = false;
819 if(fullMDPComp(ctx, list)) {
820 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700821 } else if(fullMDPCompWithPTOR(ctx, list)) {
822 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700823 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700824 ret = true;
825 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530826
Saurabh Shahaa236822013-04-24 18:07:26 -0700827 return ret;
828}
829
830bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700831
832 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
833 return false;
834
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700835 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
836 for(int i = 0; i < numAppLayers; i++) {
837 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700838 if(not mCurrentFrame.drop[i] and
839 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700840 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
841 return false;
842 }
843 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800844
Saurabh Shahaa236822013-04-24 18:07:26 -0700845 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700846 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
847 sizeof(mCurrentFrame.isFBComposed));
848 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
849 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700850
Raj Kamal389d6e32014-08-04 14:43:24 +0530851 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800852 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530853 }
854
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800855 if(!postHeuristicsHandling(ctx, list)) {
856 ALOGD_IF(isDebug(), "post heuristic handling failed");
857 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700858 return false;
859 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700860 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
861 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700862 return true;
863}
864
Sushil Chauhandefd3522014-05-13 18:17:12 -0700865/* Full MDP Composition with Peripheral Tiny Overlap Removal.
866 * MDP bandwidth limitations can be avoided, if the overlap region
867 * covered by the smallest layer at a higher z-order, gets composed
868 * by Copybit on a render buffer, which can be queued to MDP.
869 */
870bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
871 hwc_display_contents_1_t* list) {
872
873 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
874 const int stagesForMDP = min(sMaxPipesPerMixer,
875 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
876
877 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700878 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700879 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
880 return false;
881 }
882
883 // Frame level checks
884 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
885 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
886 isSecurePresent(ctx, mDpy)) {
887 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
888 return false;
889 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700890 // MDP comp checks
891 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700892 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700893 if(not isSupportedForMDPComp(ctx, layer)) {
894 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
895 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700896 }
897 }
898
Sushil Chauhandefd3522014-05-13 18:17:12 -0700899 /* We cannot use this composition mode, if:
900 1. A below layer needs scaling.
901 2. Overlap is not peripheral to display.
902 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700903 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700904 */
905
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
907 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
908 memset(overlapRect, 0, sizeof(overlapRect));
909 int layerPixelCount, minPixelCount = 0;
910 int numPTORLayersFound = 0;
911 for (int i = numAppLayers-1; (i >= 0 &&
912 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700913 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700914 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700916 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
917 // PTOR layer should be peripheral and cannot have transform
918 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
919 has90Transform(layer)) {
920 continue;
921 }
922 if((3 * (layerPixelCount + minPixelCount)) >
923 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
924 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
925 continue;
926 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700927 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700928 for (int j = i-1; j >= 0; j--) {
929 // Check if the layers below this layer qualifies for PTOR comp
930 hwc_layer_1_t* layer = &list->hwLayers[j];
931 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700932 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700933 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700934 if (isValidRect(getIntersection(dispFrame, disFrame))) {
935 if (has90Transform(layer) || needsScaling(layer)) {
936 found = false;
937 break;
938 }
939 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700940 }
941 }
942 // Store the minLayer Index
943 if(found) {
944 minLayerIndex[numPTORLayersFound] = i;
945 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
946 minPixelCount += layerPixelCount;
947 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700948 }
949 }
950
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 // No overlap layers
952 if (!numPTORLayersFound)
953 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700954
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700955 // Store the displayFrame and the sourceCrops of the layers
956 hwc_rect_t displayFrame[numAppLayers];
957 hwc_rect_t sourceCrop[numAppLayers];
958 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959 hwc_layer_1_t* layer = &list->hwLayers[i];
960 displayFrame[i] = layer->displayFrame;
961 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700962 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700963
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530964 /**
965 * It's possible that 2 PTOR layers might have overlapping.
966 * In such case, remove the intersection(again if peripheral)
967 * from the lower PTOR layer to avoid overlapping.
968 * If intersection is not on peripheral then compromise
969 * by reducing number of PTOR layers.
970 **/
971 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
972 if(isValidRect(commonRect)) {
973 overlapRect[1] = deductRect(overlapRect[1], commonRect);
974 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
975 }
976
977 ctx->mPtorInfo.count = numPTORLayersFound;
978 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
979 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
980 }
981
982 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
983 // reset PTOR
984 ctx->mPtorInfo.count = 0;
985 if(isValidRect(commonRect)) {
986 // If PTORs are intersecting restore displayframe of PTOR[1]
987 // before returning, as we have modified it above.
988 list->hwLayers[minLayerIndex[1]].displayFrame =
989 displayFrame[minLayerIndex[1]];
990 }
991 return false;
992 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700993 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
994 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
995
Xu Yangcda012c2014-07-30 21:57:21 +0800996 // Store the blending mode, planeAlpha, and transform of PTOR layers
997 int32_t blending[numPTORLayersFound];
998 uint8_t planeAlpha[numPTORLayersFound];
999 uint32_t transform[numPTORLayersFound];
1000
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001001 for(int j = 0; j < numPTORLayersFound; j++) {
1002 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001003
1004 // Update src crop of PTOR layer
1005 hwc_layer_1_t* layer = &list->hwLayers[index];
1006 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1007 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1008 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1009 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1010
1011 // Store & update w, h, format of PTOR layer
1012 private_handle_t *hnd = (private_handle_t *)layer->handle;
1013 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1014 layerWhf[j] = whf;
1015 hnd->width = renderBuf->width;
1016 hnd->height = renderBuf->height;
1017 hnd->format = renderBuf->format;
1018
Xu Yangcda012c2014-07-30 21:57:21 +08001019 // Store & update blending mode, planeAlpha and transform of PTOR layer
1020 blending[j] = layer->blending;
1021 planeAlpha[j] = layer->planeAlpha;
1022 transform[j] = layer->transform;
1023 layer->blending = HWC_BLENDING_NONE;
1024 layer->planeAlpha = 0xFF;
1025 layer->transform = 0;
1026
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001027 // Remove overlap from crop & displayFrame of below layers
1028 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001029 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001030 if(!isValidRect(getIntersection(layer->displayFrame,
1031 overlapRect[j]))) {
1032 continue;
1033 }
1034 // Update layer attributes
1035 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1036 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301037 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001038 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1039 layer->transform);
1040 layer->sourceCropf.left = (float)srcCrop.left;
1041 layer->sourceCropf.top = (float)srcCrop.top;
1042 layer->sourceCropf.right = (float)srcCrop.right;
1043 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1044 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001045 }
1046
1047 mCurrentFrame.mdpCount = numAppLayers;
1048 mCurrentFrame.fbCount = 0;
1049 mCurrentFrame.fbZ = -1;
1050
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301051 for (int j = 0; j < numAppLayers; j++) {
1052 if(isValidRect(list->hwLayers[j].displayFrame)) {
1053 mCurrentFrame.isFBComposed[j] = false;
1054 } else {
1055 mCurrentFrame.mdpCount--;
1056 mCurrentFrame.drop[j] = true;
1057 }
1058 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001059
1060 bool result = postHeuristicsHandling(ctx, list);
1061
1062 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001063 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001064 hwc_layer_1_t* layer = &list->hwLayers[i];
1065 layer->displayFrame = displayFrame[i];
1066 layer->sourceCropf.left = (float)sourceCrop[i].left;
1067 layer->sourceCropf.top = (float)sourceCrop[i].top;
1068 layer->sourceCropf.right = (float)sourceCrop[i].right;
1069 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1070 }
1071
Xu Yangcda012c2014-07-30 21:57:21 +08001072 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001073 for (int i = 0; i < numPTORLayersFound; i++) {
1074 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001075 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001076 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1077 hnd->width = layerWhf[i].w;
1078 hnd->height = layerWhf[i].h;
1079 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001080 layer->blending = blending[i];
1081 layer->planeAlpha = planeAlpha[i];
1082 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001083 }
1084
Sushil Chauhandefd3522014-05-13 18:17:12 -07001085 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001086 // reset PTOR
1087 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001088 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001089 } else {
1090 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1091 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001092 }
1093
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001094 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1095 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001096 return result;
1097}
1098
Saurabh Shahaa236822013-04-24 18:07:26 -07001099bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1100{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001101 if(!sEnableMixedMode) {
1102 //Mixed mode is disabled. No need to even try caching.
1103 return false;
1104 }
1105
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001106 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001107 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001108 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001109 cacheBasedComp(ctx, list);
1110 } else {
1111 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001112 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001113 }
1114
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001115 return ret;
1116}
1117
1118bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1119 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001120 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1121 return false;
1122
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001123 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001124 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001125 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001126
1127 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1128 for(int i = 0; i < numAppLayers; i++) {
1129 if(!mCurrentFrame.isFBComposed[i]) {
1130 hwc_layer_1_t* layer = &list->hwLayers[i];
1131 if(not isSupportedForMDPComp(ctx, layer)) {
1132 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1133 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001134 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001135 return false;
1136 }
1137 }
1138 }
1139
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001140 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001141 /* mark secure RGB layers for MDP comp */
1142 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301143 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001144 if(!ret) {
1145 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001146 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001147 return false;
1148 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001149
1150 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001151
Raj Kamal389d6e32014-08-04 14:43:24 +05301152 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001153 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301154 }
1155
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001156 if(!postHeuristicsHandling(ctx, list)) {
1157 ALOGD_IF(isDebug(), "post heuristic handling failed");
1158 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001159 return false;
1160 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001161 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1162 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001163
Saurabh Shahaa236822013-04-24 18:07:26 -07001164 return true;
1165}
1166
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001167bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001168 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001169 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1170 return false;
1171
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001172 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001173 return false;
1174 }
1175
Saurabh Shahb772ae32013-11-18 15:40:02 -08001176 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001177 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1178 const int stagesForMDP = min(sMaxPipesPerMixer,
1179 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001180
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001181 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1182 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1183 int lastMDPSupportedIndex = numAppLayers;
1184 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001185
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001186 //Find the minimum MDP batch size
1187 for(int i = 0; i < numAppLayers;i++) {
1188 if(mCurrentFrame.drop[i]) {
1189 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001190 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001191 }
1192 hwc_layer_1_t* layer = &list->hwLayers[i];
1193 if(not isSupportedForMDPComp(ctx, layer)) {
1194 lastMDPSupportedIndex = i;
1195 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1196 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001197 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001198 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001199 }
1200
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001201 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1202 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1203 mCurrentFrame.dropCount);
1204
1205 //Start at a point where the fb batch should at least have 2 layers, for
1206 //this mode to be justified.
1207 while(fbBatchSize < 2) {
1208 ++fbBatchSize;
1209 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001210 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001211
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001212 //If there are no layers for MDP, this mode doesnt make sense.
1213 if(mdpBatchSize < 1) {
1214 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1215 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001216 return false;
1217 }
1218
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001219 mCurrentFrame.reset(numAppLayers);
1220
1221 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1222 while(mdpBatchSize > 0) {
1223 //Mark layers for MDP comp
1224 int mdpBatchLeft = mdpBatchSize;
1225 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1226 if(mCurrentFrame.drop[i]) {
1227 continue;
1228 }
1229 mCurrentFrame.isFBComposed[i] = false;
1230 --mdpBatchLeft;
1231 }
1232
1233 mCurrentFrame.fbZ = mdpBatchSize;
1234 mCurrentFrame.fbCount = fbBatchSize;
1235 mCurrentFrame.mdpCount = mdpBatchSize;
1236
1237 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1238 __FUNCTION__, mdpBatchSize, fbBatchSize,
1239 mCurrentFrame.dropCount);
1240
1241 if(postHeuristicsHandling(ctx, list)) {
1242 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001243 __FUNCTION__);
1244 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1245 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001246 return true;
1247 }
1248
1249 reset(ctx);
1250 --mdpBatchSize;
1251 ++fbBatchSize;
1252 }
1253
1254 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001255}
1256
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001257bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301258 if(mDpy or isSecurePresent(ctx, mDpy) or
1259 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001260 return false;
1261 }
1262 return true;
1263}
1264
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001265bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1266 hwc_display_contents_1_t* list){
1267 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1268 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001269 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001270 return false;
1271 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001272 if(ctx->listStats[mDpy].secureUI)
1273 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001274 return true;
1275}
1276
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001277bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1278 hwc_display_contents_1_t* list) {
1279 const bool secureOnly = true;
1280 return videoOnlyComp(ctx, list, not secureOnly) or
1281 videoOnlyComp(ctx, list, secureOnly);
1282}
1283
1284bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001285 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001286 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1287 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001288 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001289
Saurabh Shahaa236822013-04-24 18:07:26 -07001290 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001291 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001292 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001293 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001294
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001295 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1296 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001297 return false;
1298 }
1299
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001300 /* Bail out if we are processing only secured video layers
1301 * and we dont have any */
1302 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001303 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001304 return false;
1305 }
1306
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001307 if(mCurrentFrame.fbCount)
1308 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001309
Raj Kamal389d6e32014-08-04 14:43:24 +05301310 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001311 adjustForSourceSplit(ctx, list);
1312 }
1313
1314 if(!postHeuristicsHandling(ctx, list)) {
1315 ALOGD_IF(isDebug(), "post heuristic handling failed");
1316 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001317 return false;
1318 }
1319
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001320 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1321 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001322 return true;
1323}
1324
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001325/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1326bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1327 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001328 // Fall back to video only composition, if AIV video mode is enabled
1329 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001330 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1331 __FUNCTION__, mDpy);
1332 return false;
1333 }
1334
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001335 const bool secureOnly = true;
1336 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1337 mdpOnlyLayersComp(ctx, list, secureOnly);
1338
1339}
1340
1341bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1342 hwc_display_contents_1_t* list, bool secureOnly) {
1343
1344 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1345 return false;
1346
1347 /* Bail out if we are processing only secured video layers
1348 * and we dont have any */
1349 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1350 reset(ctx);
1351 return false;
1352 }
1353
1354 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1355 mCurrentFrame.reset(numAppLayers);
1356 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1357
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001358 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001359 /* mark secure RGB layers for MDP comp */
1360 updateSecureRGB(ctx, list);
1361
1362 if(mCurrentFrame.mdpCount == 0) {
1363 reset(ctx);
1364 return false;
1365 }
1366
1367 /* find the maximum batch of layers to be marked for framebuffer */
1368 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1369 if(!ret) {
1370 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1371 reset(ctx);
1372 return false;
1373 }
1374
1375 if(sEnableYUVsplit){
1376 adjustForSourceSplit(ctx, list);
1377 }
1378
1379 if(!postHeuristicsHandling(ctx, list)) {
1380 ALOGD_IF(isDebug(), "post heuristic handling failed");
1381 reset(ctx);
1382 return false;
1383 }
1384
1385 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1386 __FUNCTION__);
1387 return true;
1388}
1389
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001390/* Checks for conditions where YUV layers cannot be bypassed */
1391bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001392 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001393 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001394 return false;
1395 }
1396
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001397 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001398 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1399 return false;
1400 }
1401
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001402 if(isSecuring(ctx, layer)) {
1403 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1404 return false;
1405 }
1406
Saurabh Shah4fdde762013-04-30 18:47:33 -07001407 if(!isValidDimension(ctx, layer)) {
1408 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1409 __FUNCTION__);
1410 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001411 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001412
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001413 if(layer->planeAlpha < 0xFF) {
1414 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1415 in video only mode",
1416 __FUNCTION__);
1417 return false;
1418 }
1419
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001420 return true;
1421}
1422
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001423/* Checks for conditions where Secure RGB layers cannot be bypassed */
1424bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1425 if(isSkipLayer(layer)) {
1426 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1427 __FUNCTION__, mDpy);
1428 return false;
1429 }
1430
1431 if(isSecuring(ctx, layer)) {
1432 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1433 return false;
1434 }
1435
1436 if(not isSupportedForMDPComp(ctx, layer)) {
1437 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1438 __FUNCTION__);
1439 return false;
1440 }
1441 return true;
1442}
1443
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301444/* starts at fromIndex and check for each layer to find
1445 * if it it has overlapping with any Updating layer above it in zorder
1446 * till the end of the batch. returns true if it finds any intersection */
1447bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1448 int fromIndex, int toIndex) {
1449 for(int i = fromIndex; i < toIndex; i++) {
1450 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1451 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1452 return false;
1453 }
1454 }
1455 }
1456 return true;
1457}
1458
1459/* Checks if given layer at targetLayerIndex has any
1460 * intersection with all the updating layers in beween
1461 * fromIndex and toIndex. Returns true if it finds intersectiion */
1462bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1463 int fromIndex, int toIndex, int targetLayerIndex) {
1464 for(int i = fromIndex; i <= toIndex; i++) {
1465 if(!mCurrentFrame.isFBComposed[i]) {
1466 if(areLayersIntersecting(&list->hwLayers[i],
1467 &list->hwLayers[targetLayerIndex])) {
1468 return true;
1469 }
1470 }
1471 }
1472 return false;
1473}
1474
1475int MDPComp::getBatch(hwc_display_contents_1_t* list,
1476 int& maxBatchStart, int& maxBatchEnd,
1477 int& maxBatchCount) {
1478 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301479 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001480 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301481 while (i < mCurrentFrame.layerCount) {
1482 int batchCount = 0;
1483 int batchStart = i;
1484 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001485 /* Adjust batch Z order with the dropped layers so far */
1486 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301487 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301488 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301489 while(i < mCurrentFrame.layerCount) {
1490 if(!mCurrentFrame.isFBComposed[i]) {
1491 if(!batchCount) {
1492 i++;
1493 break;
1494 }
1495 updatingLayersAbove++;
1496 i++;
1497 continue;
1498 } else {
1499 if(mCurrentFrame.drop[i]) {
1500 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001501 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301502 continue;
1503 } else if(updatingLayersAbove <= 0) {
1504 batchCount++;
1505 batchEnd = i;
1506 i++;
1507 continue;
1508 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1509
1510 // We have a valid updating layer already. If layer-i not
1511 // have overlapping with all updating layers in between
1512 // batch-start and i, then we can add layer i to batch.
1513 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1514 batchCount++;
1515 batchEnd = i;
1516 i++;
1517 continue;
1518 } else if(canPushBatchToTop(list, batchStart, i)) {
1519 //If All the non-updating layers with in this batch
1520 //does not have intersection with the updating layers
1521 //above in z-order, then we can safely move the batch to
1522 //higher z-order. Increment fbZ as it is moving up.
1523 if( firstZReverseIndex < 0) {
1524 firstZReverseIndex = i;
1525 }
1526 batchCount++;
1527 batchEnd = i;
1528 fbZ += updatingLayersAbove;
1529 i++;
1530 updatingLayersAbove = 0;
1531 continue;
1532 } else {
1533 //both failed.start the loop again from here.
1534 if(firstZReverseIndex >= 0) {
1535 i = firstZReverseIndex;
1536 }
1537 break;
1538 }
1539 }
1540 }
1541 }
1542 if(batchCount > maxBatchCount) {
1543 maxBatchCount = batchCount;
1544 maxBatchStart = batchStart;
1545 maxBatchEnd = batchEnd;
1546 fbZOrder = fbZ;
1547 }
1548 }
1549 return fbZOrder;
1550}
1551
1552bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1553 hwc_display_contents_1_t* list) {
1554 /* Idea is to keep as many non-updating(cached) layers in FB and
1555 * send rest of them through MDP. This is done in 2 steps.
1556 * 1. Find the maximum contiguous batch of non-updating layers.
1557 * 2. See if we can improve this batch size for caching by adding
1558 * opaque layers around the batch, if they don't have
1559 * any overlapping with the updating layers in between.
1560 * NEVER mark an updating layer for caching.
1561 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001562
1563 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001564 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001565 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301566 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001567
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001568 /* Nothing is cached. No batching needed */
1569 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001570 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001571 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001572
1573 /* No MDP comp layers, try to use other comp modes */
1574 if(mCurrentFrame.mdpCount == 0) {
1575 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001576 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301578 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001579
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301580 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001581 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001582 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001583 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301584 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001585 if(!mCurrentFrame.drop[i]){
1586 //If an unsupported layer is being attempted to
1587 //be pulled out we should fail
1588 if(not isSupportedForMDPComp(ctx, layer)) {
1589 return false;
1590 }
1591 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001592 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001593 }
1594 }
1595
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301596 // update the frame data
1597 mCurrentFrame.fbZ = fbZ;
1598 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001599 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001600 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001601
1602 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301603 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001604
1605 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001607
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001609 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001611 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001613 for(int i = 0; i < numAppLayers; i++) {
1614 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001615 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001616 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001617 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001618 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001619 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001620 }
1621 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001622
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001623 frame.fbCount = fbCount;
1624 frame.mdpCount = frame.layerCount - frame.fbCount
1625 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001626
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001627 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1628 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001629}
1630
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001631// drop other non-AIV layers from external display list.
1632void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001633 hwc_display_contents_1_t* list) {
1634 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1635 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001636 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001637 mCurrentFrame.dropCount++;
1638 mCurrentFrame.drop[i] = true;
1639 }
1640 }
1641 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1642 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1643 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1644 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1645 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1646 mCurrentFrame.dropCount);
1647}
1648
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001649void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001650 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001651 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1652 for(int index = 0;index < nYuvCount; index++){
1653 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1654 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1655
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001656 if(mCurrentFrame.drop[nYuvIndex]) {
1657 continue;
1658 }
1659
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001661 if(!frame.isFBComposed[nYuvIndex]) {
1662 frame.isFBComposed[nYuvIndex] = true;
1663 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664 }
1665 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001666 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001667 private_handle_t *hnd = (private_handle_t *)layer->handle;
1668 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001669 frame.isFBComposed[nYuvIndex] = false;
1670 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001671 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672 }
1673 }
1674 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001675
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001676 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1677 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678}
1679
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001680void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1681 hwc_display_contents_1_t* list) {
1682 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1683 for(int index = 0;index < nSecureRGBCount; index++){
1684 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1685 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1686
1687 if(!isSecureRGBDoable(ctx, layer)) {
1688 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1689 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1690 mCurrentFrame.fbCount++;
1691 }
1692 } else {
1693 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1694 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1695 mCurrentFrame.fbCount--;
1696 }
1697 }
1698 }
1699
1700 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1701 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1702 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1703 mCurrentFrame.fbCount);
1704}
1705
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001706hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1707 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001708 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001709
1710 /* Update only the region of FB needed for composition */
1711 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1712 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1713 hwc_layer_1_t* layer = &list->hwLayers[i];
1714 hwc_rect_t dst = layer->displayFrame;
1715 fbRect = getUnion(fbRect, dst);
1716 }
1717 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001718 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001719 return fbRect;
1720}
1721
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001722bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1723 hwc_display_contents_1_t* list) {
1724
1725 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001726 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001727 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1728 return false;
1729 }
1730
1731 //Limitations checks
1732 if(!hwLimitationsCheck(ctx, list)) {
1733 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1734 return false;
1735 }
1736
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001737 //Configure framebuffer first if applicable
1738 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001739 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001740 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1741 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001742 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1743 __FUNCTION__);
1744 return false;
1745 }
1746 }
1747
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001748 mCurrentFrame.map();
1749
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001750 if(!allocLayerPipes(ctx, list)) {
1751 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001752 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001753 }
1754
1755 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001756 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001757 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001758 int mdpIndex = mCurrentFrame.layerToMDP[index];
1759 hwc_layer_1_t* layer = &list->hwLayers[index];
1760
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301761 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1762 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1763 mdpNextZOrder++;
1764 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001765 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1766 cur_pipe->zOrder = mdpNextZOrder++;
1767
radhakrishnac9a67412013-09-25 17:40:42 +05301768 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301769 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301770 if(configure4k2kYuv(ctx, layer,
1771 mCurrentFrame.mdpToLayer[mdpIndex])
1772 != 0 ){
1773 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1774 for layer %d",__FUNCTION__, index);
1775 return false;
1776 }
1777 else{
1778 mdpNextZOrder++;
1779 }
1780 continue;
1781 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001782 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1783 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301784 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001785 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001786 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001787 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788 }
1789
Saurabh Shaha36be922013-12-16 18:18:39 -08001790 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1791 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1792 ,__FUNCTION__, mDpy);
1793 return false;
1794 }
1795
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001796 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001797 return true;
1798}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001799
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001800bool MDPComp::resourceCheck(hwc_context_t* ctx,
1801 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001802 const bool fbUsed = mCurrentFrame.fbCount;
1803 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1804 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1805 return false;
1806 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001807
1808 //Will benefit cases where a video has non-updating background.
1809 if((mDpy > HWC_DISPLAY_PRIMARY) and
1810 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1811 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1812 return false;
1813 }
1814
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001815 // Init rotCount to number of rotate sessions used by other displays
1816 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1817 // Count the number of rotator sessions required for current display
1818 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1819 if(!mCurrentFrame.isFBComposed[index]) {
1820 hwc_layer_1_t* layer = &list->hwLayers[index];
1821 private_handle_t *hnd = (private_handle_t *)layer->handle;
1822 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1823 rotCount++;
1824 }
1825 }
1826 }
1827 // if number of layers to rotate exceeds max rotator sessions, bail out.
1828 if(rotCount > RotMgr::MAX_ROT_SESS) {
1829 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1830 __FUNCTION__, mDpy);
1831 return false;
1832 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001833 return true;
1834}
1835
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301836bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1837 hwc_display_contents_1_t* list) {
1838
1839 //A-family hw limitation:
1840 //If a layer need alpha scaling, MDP can not support.
1841 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1842 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1843 if(!mCurrentFrame.isFBComposed[i] &&
1844 isAlphaScaled( &list->hwLayers[i])) {
1845 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1846 return false;
1847 }
1848 }
1849 }
1850
1851 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1852 //If multiple layers requires downscaling and also they are overlapping
1853 //fall back to GPU since MDSS can not handle it.
1854 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1855 qdutils::MDPVersion::getInstance().is8x26()) {
1856 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1857 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1858 if(!mCurrentFrame.isFBComposed[i] &&
1859 isDownscaleRequired(botLayer)) {
1860 //if layer-i is marked for MDP and needs downscaling
1861 //check if any MDP layer on top of i & overlaps with layer-i
1862 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1863 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1864 if(!mCurrentFrame.isFBComposed[j] &&
1865 isDownscaleRequired(topLayer)) {
1866 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1867 topLayer->displayFrame);
1868 if(isValidRect(r))
1869 return false;
1870 }
1871 }
1872 }
1873 }
1874 }
1875 return true;
1876}
1877
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001878int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001879 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001880 char property[PROPERTY_VALUE_MAX];
1881
Raj Kamal4393eaa2014-06-06 13:45:20 +05301882 if(!ctx || !list) {
1883 ALOGE("%s: Invalid context or list",__FUNCTION__);
1884 mCachedFrame.reset();
1885 return -1;
1886 }
1887
1888 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001889 if(mDpy == HWC_DISPLAY_PRIMARY) {
1890 sSimulationFlags = 0;
1891 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1892 int currentFlags = atoi(property);
1893 if(currentFlags != sSimulationFlags) {
1894 sSimulationFlags = currentFlags;
1895 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1896 sSimulationFlags, sSimulationFlags);
1897 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001898 }
1899 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001900 // reset PTOR
1901 if(!mDpy)
1902 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001903
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301904 //Do not cache the information for next draw cycle.
1905 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1906 ALOGI("%s: Unsupported layer count for mdp composition",
1907 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001908 mCachedFrame.reset();
1909 return -1;
1910 }
1911
Saurabh Shahb39f8152013-08-22 10:21:44 -07001912 //reset old data
1913 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001914 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1915 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301916
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001917 // Detect the start of animation and fall back to GPU only once to cache
1918 // all the layers in FB and display FB content untill animation completes.
1919 if(ctx->listStats[mDpy].isDisplayAnimating) {
1920 mCurrentFrame.needsRedraw = false;
1921 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1922 mCurrentFrame.needsRedraw = true;
1923 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1924 }
1925 setMDPCompLayerFlags(ctx, list);
1926 mCachedFrame.updateCounts(mCurrentFrame);
1927 ret = -1;
1928 return ret;
1929 } else {
1930 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1931 }
1932
Saurabh Shahb39f8152013-08-22 10:21:44 -07001933 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001934 if(isFrameDoable(ctx)) {
1935 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001936 // if AIV Video mode is enabled, drop all non AIV layers from the
1937 // external display list.
1938 if(ctx->listStats[mDpy].mAIVVideoMode) {
1939 dropNonAIVLayers(ctx, list);
1940 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001941
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001942 // if tryFullFrame fails, try to push all video and secure RGB layers
1943 // to MDP for composition.
1944 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001945 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301946 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001947 setMDPCompLayerFlags(ctx, list);
1948 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001949 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001950 reset(ctx);
1951 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1952 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001953 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001954 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1955 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001956 }
1957 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301958 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1959 enablePartialUpdateForMDP3) {
1960 generateROI(ctx, list);
1961 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1962 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1963 }
1964 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001965 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1966 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001967 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001968 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001969
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001970 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001971 ALOGD("GEOMETRY change: %d",
1972 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001973 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001974 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001975 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001976 }
1977
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001978#ifdef DYNAMIC_FPS
1979 //For primary display, set the dynamic refreshrate
Raj Kamal0d53fc62014-11-25 17:36:36 +05301980 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1981 ctx->mUseMetaDataRefreshRate) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001982 FrameInfo frame;
1983 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301984 memset(&frame.drop, 0, sizeof(frame.drop));
1985 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001986 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1987 __FUNCTION__);
1988 updateLayerCache(ctx, list, frame);
1989 updateYUV(ctx, list, false /*secure only*/, frame);
1990 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1991 //Set the new fresh rate, if there is only one updating YUV layer
1992 //or there is one single RGB layer with this request
1993 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1994 (frame.layerCount == 1)) {
1995 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1996 }
1997 setRefreshRate(ctx, mDpy, refreshRate);
1998 }
1999#endif
2000
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002001 mCachedFrame.cacheAll(list);
2002 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002003 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002004}
2005
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002006bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302007
2008 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302009 int mdpIndex = mCurrentFrame.layerToMDP[index];
2010 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2011 info.pipeInfo = new MdpYUVPipeInfo;
2012 info.rot = NULL;
2013 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302014
2015 pipe_info.lIndex = ovutils::OV_INVALID;
2016 pipe_info.rIndex = ovutils::OV_INVALID;
2017
Saurabh Shahc62f3982014-03-05 14:28:26 -08002018 Overlay::PipeSpecs pipeSpecs;
2019 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2020 pipeSpecs.needsScaling = true;
2021 pipeSpecs.dpy = mDpy;
2022 pipeSpecs.fb = false;
2023
2024 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302025 if(pipe_info.lIndex == ovutils::OV_INVALID){
2026 bRet = false;
2027 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2028 __FUNCTION__);
2029 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002030 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302031 if(pipe_info.rIndex == ovutils::OV_INVALID){
2032 bRet = false;
2033 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2034 __FUNCTION__);
2035 }
2036 return bRet;
2037}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002038
2039int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2040 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002041 if (ctx->mPtorInfo.isActive()) {
2042 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002043 if (fd < 0) {
2044 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002045 }
2046 }
2047 return fd;
2048}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002049//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002050
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002051void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302052 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002053 //If 4k2k Yuv layer split is possible, and if
2054 //fbz is above 4k2k layer, increment fb zorder by 1
2055 //as we split 4k2k layer and increment zorder for right half
2056 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002057 if(!ctx)
2058 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002059 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302060 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2061 index++) {
2062 if(!mCurrentFrame.isFBComposed[index]) {
2063 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2064 mdpNextZOrder++;
2065 }
2066 mdpNextZOrder++;
2067 hwc_layer_1_t* layer = &list->hwLayers[index];
2068 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302069 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302070 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2071 mCurrentFrame.fbZ += 1;
2072 mdpNextZOrder++;
2073 //As we split 4kx2k yuv layer and program to 2 VG pipes
2074 //(if available) increase mdpcount by 1.
2075 mCurrentFrame.mdpCount++;
2076 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002077 }
2078 }
2079 }
radhakrishnac9a67412013-09-25 17:40:42 +05302080}
2081
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002082/*
2083 * Configures pipe(s) for MDP composition
2084 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002085int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002086 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002087 MdpPipeInfoNonSplit& mdp_info =
2088 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302089 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002090 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002091 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002092
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002093 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2094 __FUNCTION__, layer, zOrder, dest);
2095
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002096 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002097 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002098}
2099
Saurabh Shah88e4d272013-09-03 13:31:29 -07002100bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002101 hwc_display_contents_1_t* list) {
2102 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002103
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002104 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002105
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002106 hwc_layer_1_t* layer = &list->hwLayers[index];
2107 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302108 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002109 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302110 continue;
2111 }
2112 }
2113
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002114 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002115 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002116 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002117 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002118 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002119
Saurabh Shahc62f3982014-03-05 14:28:26 -08002120 Overlay::PipeSpecs pipeSpecs;
2121 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2122 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2123 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2124 (qdutils::MDPVersion::getInstance().is8x26() and
2125 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2126 pipeSpecs.dpy = mDpy;
2127 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002128 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002129
Saurabh Shahc62f3982014-03-05 14:28:26 -08002130 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2131
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002132 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002133 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002134 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002135 }
2136 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137 return true;
2138}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002139
radhakrishnac9a67412013-09-25 17:40:42 +05302140int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2141 PipeLayerPair& PipeLayerPair) {
2142 MdpYUVPipeInfo& mdp_info =
2143 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2144 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302145 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302146 eDest lDest = mdp_info.lIndex;
2147 eDest rDest = mdp_info.rIndex;
2148
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002149 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302150 lDest, rDest, &PipeLayerPair.rot);
2151}
2152
Saurabh Shah88e4d272013-09-03 13:31:29 -07002153bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002154
Raj Kamal4393eaa2014-06-06 13:45:20 +05302155 if(!isEnabled() or !mModeOn) {
2156 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302157 return true;
2158 }
2159
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002160 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002161 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002162 sHandleTimeout = true;
2163 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002164
2165 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002166 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002167
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002168 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2169 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002170 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002171 if(mCurrentFrame.isFBComposed[i]) continue;
2172
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002173 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002174 private_handle_t *hnd = (private_handle_t *)layer->handle;
2175 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002176 if (!(layer->flags & HWC_COLOR_FILL)) {
2177 ALOGE("%s handle null", __FUNCTION__);
2178 return false;
2179 }
2180 // No PLAY for Color layer
2181 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2182 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002183 }
2184
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002185 int mdpIndex = mCurrentFrame.layerToMDP[i];
2186
Raj Kamal389d6e32014-08-04 14:43:24 +05302187 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302188 {
2189 MdpYUVPipeInfo& pipe_info =
2190 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2191 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2192 ovutils::eDest indexL = pipe_info.lIndex;
2193 ovutils::eDest indexR = pipe_info.rIndex;
2194 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302195 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302196 if(rot) {
2197 rot->queueBuffer(fd, offset);
2198 fd = rot->getDstMemId();
2199 offset = rot->getDstOffset();
2200 }
2201 if(indexL != ovutils::OV_INVALID) {
2202 ovutils::eDest destL = (ovutils::eDest)indexL;
2203 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2204 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2205 if (!ov.queueBuffer(fd, offset, destL)) {
2206 ALOGE("%s: queueBuffer failed for display:%d",
2207 __FUNCTION__, mDpy);
2208 return false;
2209 }
2210 }
2211
2212 if(indexR != ovutils::OV_INVALID) {
2213 ovutils::eDest destR = (ovutils::eDest)indexR;
2214 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2215 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2216 if (!ov.queueBuffer(fd, offset, destR)) {
2217 ALOGE("%s: queueBuffer failed for display:%d",
2218 __FUNCTION__, mDpy);
2219 return false;
2220 }
2221 }
2222 }
2223 else{
2224 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002225 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302226 ovutils::eDest dest = pipe_info.index;
2227 if(dest == ovutils::OV_INVALID) {
2228 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002229 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302230 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002231
radhakrishnac9a67412013-09-25 17:40:42 +05302232 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2233 continue;
2234 }
2235
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002236 int fd = hnd->fd;
2237 uint32_t offset = (uint32_t)hnd->offset;
2238 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2239 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002240 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002241 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002242 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002243 }
2244
radhakrishnac9a67412013-09-25 17:40:42 +05302245 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2246 using pipe: %d", __FUNCTION__, layer,
2247 hnd, dest );
2248
radhakrishnac9a67412013-09-25 17:40:42 +05302249 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2250 if(rot) {
2251 if(!rot->queueBuffer(fd, offset))
2252 return false;
2253 fd = rot->getDstMemId();
2254 offset = rot->getDstOffset();
2255 }
2256
2257 if (!ov.queueBuffer(fd, offset, dest)) {
2258 ALOGE("%s: queueBuffer failed for display:%d ",
2259 __FUNCTION__, mDpy);
2260 return false;
2261 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002262 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002263
2264 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002265 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002266 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002267}
2268
Saurabh Shah88e4d272013-09-03 13:31:29 -07002269//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002270
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002271void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302272 hwc_display_contents_1_t* list){
2273 //if 4kx2k yuv layer is totally present in either in left half
2274 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302275 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302276 if(mCurrentFrame.fbZ >= 0) {
2277 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2278 index++) {
2279 if(!mCurrentFrame.isFBComposed[index]) {
2280 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2281 mdpNextZOrder++;
2282 }
2283 mdpNextZOrder++;
2284 hwc_layer_1_t* layer = &list->hwLayers[index];
2285 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302286 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302287 hwc_rect_t dst = layer->displayFrame;
2288 if((dst.left > lSplit) || (dst.right < lSplit)) {
2289 mCurrentFrame.mdpCount += 1;
2290 }
2291 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2292 mCurrentFrame.fbZ += 1;
2293 mdpNextZOrder++;
2294 }
2295 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002296 }
radhakrishnac9a67412013-09-25 17:40:42 +05302297 }
2298}
2299
Saurabh Shah88e4d272013-09-03 13:31:29 -07002300bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002301 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002302
Saurabh Shahc62f3982014-03-05 14:28:26 -08002303 const int lSplit = getLeftSplit(ctx, mDpy);
2304 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002305 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002306 pipe_info.lIndex = ovutils::OV_INVALID;
2307 pipe_info.rIndex = ovutils::OV_INVALID;
2308
Saurabh Shahc62f3982014-03-05 14:28:26 -08002309 Overlay::PipeSpecs pipeSpecs;
2310 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2311 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2312 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2313 pipeSpecs.dpy = mDpy;
2314 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2315 pipeSpecs.fb = false;
2316
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002317 // Acquire pipe only for the updating half
2318 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2319 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2320
2321 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002322 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002323 if(pipe_info.lIndex == ovutils::OV_INVALID)
2324 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002325 }
2326
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002327 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002328 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2329 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002330 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002331 return false;
2332 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002333
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002334 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002335}
2336
Saurabh Shah88e4d272013-09-03 13:31:29 -07002337bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002338 hwc_display_contents_1_t* list) {
2339 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002340
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002341 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002342
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002343 hwc_layer_1_t* layer = &list->hwLayers[index];
2344 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302345 hwc_rect_t dst = layer->displayFrame;
2346 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302347 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302348 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002349 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302350 continue;
2351 }
2352 }
2353 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002354 int mdpIndex = mCurrentFrame.layerToMDP[index];
2355 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002356 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002357 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002358 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002359
Saurabh Shahc62f3982014-03-05 14:28:26 -08002360 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2361 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2362 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002363 return false;
2364 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002365 }
2366 return true;
2367}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002368
radhakrishnac9a67412013-09-25 17:40:42 +05302369int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2370 PipeLayerPair& PipeLayerPair) {
2371 const int lSplit = getLeftSplit(ctx, mDpy);
2372 hwc_rect_t dst = layer->displayFrame;
2373 if((dst.left > lSplit)||(dst.right < lSplit)){
2374 MdpYUVPipeInfo& mdp_info =
2375 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2376 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302377 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302378 eDest lDest = mdp_info.lIndex;
2379 eDest rDest = mdp_info.rIndex;
2380
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002381 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302382 lDest, rDest, &PipeLayerPair.rot);
2383 }
2384 else{
2385 return configure(ctx, layer, PipeLayerPair);
2386 }
2387}
2388
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002389/*
2390 * Configures pipe(s) for MDP composition
2391 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002392int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002393 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002394 MdpPipeInfoSplit& mdp_info =
2395 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002396 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302397 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002398 eDest lDest = mdp_info.lIndex;
2399 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002400
2401 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2402 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2403
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002404 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002405 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002406}
2407
Saurabh Shah88e4d272013-09-03 13:31:29 -07002408bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002409
Raj Kamal4393eaa2014-06-06 13:45:20 +05302410 if(!isEnabled() or !mModeOn) {
2411 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302412 return true;
2413 }
2414
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002415 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002416 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002417 sHandleTimeout = true;
2418 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002419
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002420 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002421 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002422
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002423 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2424 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002425 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002426 if(mCurrentFrame.isFBComposed[i]) continue;
2427
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002428 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002429 private_handle_t *hnd = (private_handle_t *)layer->handle;
2430 if(!hnd) {
2431 ALOGE("%s handle null", __FUNCTION__);
2432 return false;
2433 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002434
2435 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2436 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002437 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002438
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002439 int mdpIndex = mCurrentFrame.layerToMDP[i];
2440
Raj Kamal389d6e32014-08-04 14:43:24 +05302441 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302442 {
2443 MdpYUVPipeInfo& pipe_info =
2444 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2445 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2446 ovutils::eDest indexL = pipe_info.lIndex;
2447 ovutils::eDest indexR = pipe_info.rIndex;
2448 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302449 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302450 if(rot) {
2451 rot->queueBuffer(fd, offset);
2452 fd = rot->getDstMemId();
2453 offset = rot->getDstOffset();
2454 }
2455 if(indexL != ovutils::OV_INVALID) {
2456 ovutils::eDest destL = (ovutils::eDest)indexL;
2457 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2458 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2459 if (!ov.queueBuffer(fd, offset, destL)) {
2460 ALOGE("%s: queueBuffer failed for display:%d",
2461 __FUNCTION__, mDpy);
2462 return false;
2463 }
2464 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002465
radhakrishnac9a67412013-09-25 17:40:42 +05302466 if(indexR != ovutils::OV_INVALID) {
2467 ovutils::eDest destR = (ovutils::eDest)indexR;
2468 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2469 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2470 if (!ov.queueBuffer(fd, offset, destR)) {
2471 ALOGE("%s: queueBuffer failed for display:%d",
2472 __FUNCTION__, mDpy);
2473 return false;
2474 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002475 }
2476 }
radhakrishnac9a67412013-09-25 17:40:42 +05302477 else{
2478 MdpPipeInfoSplit& pipe_info =
2479 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2480 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002481
radhakrishnac9a67412013-09-25 17:40:42 +05302482 ovutils::eDest indexL = pipe_info.lIndex;
2483 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002484
radhakrishnac9a67412013-09-25 17:40:42 +05302485 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002486 uint32_t offset = (uint32_t)hnd->offset;
2487 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2488 if (!mDpy && (index != -1)) {
2489 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2490 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002491 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002492 }
radhakrishnac9a67412013-09-25 17:40:42 +05302493
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002494 if(ctx->mAD->draw(ctx, fd, offset)) {
2495 fd = ctx->mAD->getDstFd();
2496 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002497 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002498
radhakrishnac9a67412013-09-25 17:40:42 +05302499 if(rot) {
2500 rot->queueBuffer(fd, offset);
2501 fd = rot->getDstMemId();
2502 offset = rot->getDstOffset();
2503 }
2504
2505 //************* play left mixer **********
2506 if(indexL != ovutils::OV_INVALID) {
2507 ovutils::eDest destL = (ovutils::eDest)indexL;
2508 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2509 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2510 if (!ov.queueBuffer(fd, offset, destL)) {
2511 ALOGE("%s: queueBuffer failed for left mixer",
2512 __FUNCTION__);
2513 return false;
2514 }
2515 }
2516
2517 //************* play right mixer **********
2518 if(indexR != ovutils::OV_INVALID) {
2519 ovutils::eDest destR = (ovutils::eDest)indexR;
2520 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2521 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2522 if (!ov.queueBuffer(fd, offset, destR)) {
2523 ALOGE("%s: queueBuffer failed for right mixer",
2524 __FUNCTION__);
2525 return false;
2526 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002527 }
2528 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002529
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002530 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2531 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002532
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002533 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002534}
Saurabh Shahab47c692014-02-12 18:45:57 -08002535
2536//================MDPCompSrcSplit==============================================
2537bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002538 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002539 private_handle_t *hnd = (private_handle_t *)layer->handle;
2540 hwc_rect_t dst = layer->displayFrame;
2541 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2542 pipe_info.lIndex = ovutils::OV_INVALID;
2543 pipe_info.rIndex = ovutils::OV_INVALID;
2544
2545 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2546 //should have a higher priority than the right one. Pipe priorities are
2547 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002548
Saurabh Shahc62f3982014-03-05 14:28:26 -08002549 Overlay::PipeSpecs pipeSpecs;
2550 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2551 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2552 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2553 pipeSpecs.dpy = mDpy;
2554 pipeSpecs.fb = false;
2555
Saurabh Shahab47c692014-02-12 18:45:57 -08002556 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002557 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002558 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002559 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002560 }
2561
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002562 /* Use 2 pipes IF
2563 a) Layer's crop width is > 2048 or
2564 b) Layer's dest width > 2048 or
2565 c) On primary, driver has indicated with caps to split always. This is
2566 based on an empirically derived value of panel height. Applied only
2567 if the layer's width is > mixer's width
2568 */
2569
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302570 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002571 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302572 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002573 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2574 const uint32_t dstWidth = dst.right - dst.left;
2575 const uint32_t dstHeight = dst.bottom - dst.top;
2576 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002577 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002578 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2579 crop.bottom - crop.top;
2580 //Approximation to actual clock, ignoring the common factors in pipe and
2581 //mixer cases like line_time
2582 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2583 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002584
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002585 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2586 //pipe line length, we are still using 2 pipes. This is fine just because
2587 //this is source split where destination doesn't matter. Evaluate later to
2588 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002589 if(dstWidth > mdpHw.getMaxMixerWidth() or
2590 cropWidth > mdpHw.getMaxMixerWidth() or
2591 (primarySplitAlways and
2592 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002593 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002594 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002595 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002596 }
2597
2598 // Return values
2599 // 1 Left pipe is higher priority, do nothing.
2600 // 0 Pipes of same priority.
2601 //-1 Right pipe is of higher priority, needs swap.
2602 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2603 pipe_info.rIndex) == -1) {
2604 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002605 }
2606 }
2607
2608 return true;
2609}
2610
Saurabh Shahab47c692014-02-12 18:45:57 -08002611int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2612 PipeLayerPair& PipeLayerPair) {
2613 private_handle_t *hnd = (private_handle_t *)layer->handle;
2614 if(!hnd) {
2615 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2616 return -1;
2617 }
2618 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2619 MdpPipeInfoSplit& mdp_info =
2620 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2621 Rotator **rot = &PipeLayerPair.rot;
2622 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002623 eDest lDest = mdp_info.lIndex;
2624 eDest rDest = mdp_info.rIndex;
2625 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2626 hwc_rect_t dst = layer->displayFrame;
2627 int transform = layer->transform;
2628 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002629 int rotFlags = ROT_FLAGS_NONE;
2630 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2631 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2632
2633 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2634 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2635
2636 // Handle R/B swap
2637 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2638 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2639 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2640 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2641 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2642 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002643 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002644 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2645 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002646 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002647 /* Calculate the external display position based on MDP downscale,
2648 ActionSafe, and extorientation features. */
2649 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002650
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002651 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302652 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002653 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002654
2655 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2656 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002657 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002658 }
2659
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002660 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002661 (*rot) = ctx->mRotMgr->getNext();
2662 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002663 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002664 //If the video is using a single pipe, enable BWC
2665 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002666 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2667 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002668 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002669 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002670 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002671 ALOGE("%s: configRotator failed!", __FUNCTION__);
2672 return -1;
2673 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002674 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002675 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002676 }
2677
2678 //If 2 pipes being used, divide layer into half, crop and dst
2679 hwc_rect_t cropL = crop;
2680 hwc_rect_t cropR = crop;
2681 hwc_rect_t dstL = dst;
2682 hwc_rect_t dstR = dst;
2683 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2684 cropL.right = (crop.right + crop.left) / 2;
2685 cropR.left = cropL.right;
2686 sanitizeSourceCrop(cropL, cropR, hnd);
2687
Saurabh Shahb729b192014-08-15 18:04:24 -07002688 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002689 //Swap crops on H flip since 2 pipes are being used
2690 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2691 hwc_rect_t tmp = cropL;
2692 cropL = cropR;
2693 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002694 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002695 }
2696
Saurabh Shahb729b192014-08-15 18:04:24 -07002697 //cropSwap trick: If the src and dst widths are both odd, let us say
2698 //2507, then splitting both into half would cause left width to be 1253
2699 //and right 1254. If crop is swapped because of H flip, this will cause
2700 //left crop width to be 1254, whereas left dst width remains 1253, thus
2701 //inducing a scaling that is unaccounted for. To overcome that we add 1
2702 //to the dst width if there is a cropSwap. So if the original width was
2703 //2507, the left dst width will be 1254. Even if the original width was
2704 //even for ex: 2508, the left dst width will still remain 1254.
2705 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002706 dstR.left = dstL.right;
2707 }
2708
2709 //For the mdp, since either we are pre-rotating or MDP does flips
2710 orient = OVERLAY_TRANSFORM_0;
2711 transform = 0;
2712
2713 //configure left pipe
2714 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002715 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002716 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2717 (ovutils::eBlending) getBlending(layer->blending));
2718
2719 if(configMdp(ctx->mOverlay, pargL, orient,
2720 cropL, dstL, metadata, lDest) < 0) {
2721 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2722 return -1;
2723 }
2724 }
2725
2726 //configure right pipe
2727 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002728 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002729 static_cast<eRotFlags>(rotFlags),
2730 layer->planeAlpha,
2731 (ovutils::eBlending) getBlending(layer->blending));
2732 if(configMdp(ctx->mOverlay, pargR, orient,
2733 cropR, dstR, metadata, rDest) < 0) {
2734 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2735 return -1;
2736 }
2737 }
2738
2739 return 0;
2740}
2741
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002742int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2743 Locker::Autolock _l(ctx->mDrawLock);
2744 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2745 char path[MAX_SYSFS_FILE_PATH];
2746 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2747 int fd = open(path, O_WRONLY);
2748 if(fd < 0) {
2749 ALOGE("%s: Failed to open sysfd node", __FUNCTION__);
2750 return -1;
2751 }
2752 char value[4];
2753 snprintf(value, sizeof(value), "%d", (int)enable);
2754 ssize_t ret = write(fd, value, strlen(value));
2755 if(ret <= 0) {
2756 ALOGE("%s: Failed to write to sysfd nodes", __FUNCTION__);
2757 close(fd);
2758 return -1;
2759 }
2760 close(fd);
2761 sIsPartialUpdateActive = enable;
2762 return 0;
2763}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002764}; //namespace
2765