blob: 4312decd2d1706ca0268e430d872b78be5d58672 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, 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>
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080022#include <dlfcn.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070023#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070030#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080031
Saurabh Shah85234ec2013-04-12 17:09:00 -070032using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070033using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080034using namespace overlay::utils;
35namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037namespace qhwc {
38
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080039//==============MDPComp========================================================
40
Saurabh Shah59562ff2014-09-30 16:13:12 -070041IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080043bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070044bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050045bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070046bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070047int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070048int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053049bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070050bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080051int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053052bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070053bool MDPComp::sIsPartialUpdateActive = true;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080054void *MDPComp::sLibPerfHint = NULL;
55int MDPComp::sPerfLockHandle = 0;
56int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
57int (*MDPComp::sPerfLockRelease)(int value) = NULL;
58int MDPComp::sPerfHintWindow = -1;
59
Saurabh Shah88e4d272013-09-03 13:31:29 -070060MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070061 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
62 sSrcSplitEnabled = true;
63 return new MDPCompSrcSplit(dpy);
64 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070065 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080066 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070067 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080068}
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070MDPComp::MDPComp(int dpy):mDpy(dpy){};
71
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070072void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080073{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070074 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
75 return;
76
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080077 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070078 (mDpy == 0) ? "\"PRIMARY\"" :
79 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070080 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
81 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080082 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
83 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
84 (mCurrentFrame.needsRedraw? "YES" : "NO"),
85 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070086 if(isDisplaySplit(ctx, mDpy)) {
87 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
88 "Right: [%d, %d, %d, %d] \n",
89 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
90 ctx->listStats[mDpy].lRoi.right,
91 ctx->listStats[mDpy].lRoi.bottom,
92 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
93 ctx->listStats[mDpy].rRoi.right,
94 ctx->listStats[mDpy].rRoi.bottom);
95 } else {
96 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
97 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
98 ctx->listStats[mDpy].lRoi.right,
99 ctx->listStats[mDpy].lRoi.bottom);
100 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 dumpsys_log(buf," --------------------------------------------- \n");
102 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
103 dumpsys_log(buf," --------------------------------------------- \n");
104 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
105 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
106 index,
107 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700108 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800109 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700110 (mCurrentFrame.drop[index] ? "DROP" :
111 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800112 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
113 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
114 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115}
116
117bool MDPComp::init(hwc_context_t *ctx) {
118
119 if(!ctx) {
120 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
121 return false;
122 }
123
Saurabh Shah59562ff2014-09-30 16:13:12 -0700124 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800125
126 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530127 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
128 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800131 sEnabled = true;
132 }
133
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700134 sEnableMixedMode = true;
135 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
136 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
137 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
138 sEnableMixedMode = false;
139 }
140
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700141 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
142
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800143 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700144 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700145 int val = atoi(property);
146 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700147 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800148 }
149
Saurabh Shahacec8e42014-11-25 11:07:04 -0800150 /* Maximum layers allowed to use MDP on secondary panels. If property
151 * doesn't exist, default to 1. Using the property it can be set to 0 or
152 * more.
153 */
154 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
155 int val = atoi(property);
156 sMaxSecLayers = (val >= 0) ? val : 1;
157 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
158 }
159
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700161 sIdleInvalidator = IdleInvalidator::getInstance();
162 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
163 delete sIdleInvalidator;
164 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400165 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800166 }
radhakrishnac9a67412013-09-25 17:40:42 +0530167
Saurabh Shah7c727642014-06-02 15:47:14 -0700168 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700169 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700170 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
171 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
172 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530173 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530174 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700175
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530176 bool defaultPTOR = false;
177 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
178 //8x16 and 8x39 targets by default
179 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
180 (qdutils::MDPVersion::getInstance().is8x16() ||
181 qdutils::MDPVersion::getInstance().is8x39())) {
182 defaultPTOR = true;
183 }
184
185 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
186 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700187 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
188 HWC_DISPLAY_PRIMARY);
189 }
190
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530191 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
192 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
193 enablePartialUpdateForMDP3 = true;
194 }
195
196 if(!enablePartialUpdateForMDP3 &&
197 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
198 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
199 enablePartialUpdateForMDP3 = true;
200 }
201
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800202 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
203
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800204 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
205 int val = atoi(property);
206 if(val > 0 && loadPerfLib()) {
207 sPerfHintWindow = val;
208 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
209 }
210 }
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212 return true;
213}
214
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800215void MDPComp::reset(hwc_context_t *ctx) {
216 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700217 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800218 ctx->mOverlay->clear(mDpy);
219 ctx->mLayerRotMap[mDpy]->clear();
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530220 resetROI(ctx, mDpy);
221 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
222 mCurrentFrame.dropCount = 0;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700223}
224
Raj Kamal4393eaa2014-06-06 13:45:20 +0530225void MDPComp::reset() {
226 sHandleTimeout = false;
227 mModeOn = false;
228}
229
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700230void MDPComp::timeout_handler(void *udata) {
231 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
232
233 if(!ctx) {
234 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
235 return;
236 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530237
238 ctx->mDrawLock.lock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800239 // Handle timeout event only if the previous composition is MDP or MIXED.
240 if(!sHandleTimeout) {
241 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530242 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800243 return;
244 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700245 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700246 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530247 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700248 return;
249 }
250 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530251 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700252 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700253 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700254}
255
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700256void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
257 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800258 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700259 if(value > maxSupported) {
260 ALOGW("%s: Input exceeds max value supported. Setting to"
261 "max value: %d", __FUNCTION__, maxSupported);
262 }
263 sMaxPipesPerMixer = min(value, maxSupported);
264}
265
Saurabh Shah59562ff2014-09-30 16:13:12 -0700266void MDPComp::setIdleTimeout(const uint32_t& timeout) {
267 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
268
269 if(sIdleInvalidator) {
270 if(timeout <= ONE_REFRESH_PERIOD_MS) {
271 //If the specified timeout is < 1 draw cycle worth, "virtually"
272 //disable idle timeout. The ideal way for clients to disable
273 //timeout is to set it to 0
274 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
275 ALOGI("Disabled idle timeout");
276 return;
277 }
278 sIdleInvalidator->setIdleTimeout(timeout);
279 ALOGI("Idle timeout set to %u", timeout);
280 } else {
281 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
282 }
283}
284
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800285void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 hwc_display_contents_1_t* list) {
287 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800288
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800289 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800290 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800291 if(!mCurrentFrame.isFBComposed[index]) {
292 layerProp[index].mFlags |= HWC_MDPCOMP;
293 layer->compositionType = HWC_OVERLAY;
294 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800295 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700296 /* Drop the layer when its already present in FB OR when it lies
297 * outside frame's ROI */
298 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800299 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700300 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800301 }
302 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700303}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500304
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800305void MDPComp::setRedraw(hwc_context_t *ctx,
306 hwc_display_contents_1_t* list) {
307 mCurrentFrame.needsRedraw = false;
308 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
309 (list->flags & HWC_GEOMETRY_CHANGED) ||
310 isSkipPresent(ctx, mDpy)) {
311 mCurrentFrame.needsRedraw = true;
312 }
313}
314
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700316 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700317 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800318}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800319
Saurabh Shahaa236822013-04-24 18:07:26 -0700320void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700321 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800322 if(mdpToLayer[i].pipeInfo) {
323 delete mdpToLayer[i].pipeInfo;
324 mdpToLayer[i].pipeInfo = NULL;
325 //We dont own the rotator
326 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800327 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800328 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800329
330 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
331 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700332 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800333
Saurabh Shahaa236822013-04-24 18:07:26 -0700334 layerCount = numLayers;
335 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700337 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800338 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800339}
340
Saurabh Shahaa236822013-04-24 18:07:26 -0700341void MDPComp::FrameInfo::map() {
342 // populate layer and MDP maps
343 int mdpIdx = 0;
344 for(int idx = 0; idx < layerCount; idx++) {
345 if(!isFBComposed[idx]) {
346 mdpToLayer[mdpIdx].listIndex = idx;
347 layerToMDP[idx] = mdpIdx++;
348 }
349 }
350}
351
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800352MDPComp::LayerCache::LayerCache() {
353 reset();
354}
355
356void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700357 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530358 memset(&isFBComposed, true, sizeof(isFBComposed));
359 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800360 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700361}
362
363void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530364 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700365 for(int i = 0; i < numAppLayers; i++) {
366 hnd[i] = list->hwLayers[i].handle;
367 }
368}
369
370void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700371 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530372 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
373 memcpy(&drop, &curFrame.drop, sizeof(drop));
374}
375
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800376bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
377 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530378 if(layerCount != curFrame.layerCount)
379 return false;
380 for(int i = 0; i < curFrame.layerCount; i++) {
381 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
382 (curFrame.drop[i] != drop[i])) {
383 return false;
384 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800385 if(curFrame.isFBComposed[i] &&
386 (hnd[i] != list->hwLayers[i].handle)){
387 return false;
388 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530389 }
390 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800391}
392
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700393bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
394 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800395 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700396 (not isValidDimension(ctx,layer))
397 //More conditions here, SKIP, sRGB+Blend etc
398 ) {
399 return false;
400 }
401 return true;
402}
403
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530404bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800405 private_handle_t *hnd = (private_handle_t *)layer->handle;
406
407 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700408 if (layer->flags & HWC_COLOR_FILL) {
409 // Color layer
410 return true;
411 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700412 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800413 return false;
414 }
415
Naseer Ahmede850a802013-09-06 13:12:52 -0400416 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400417 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400418 return false;
419
Saurabh Shah62e1d732013-09-17 10:44:05 -0700420 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700421 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700422 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700423 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
424 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700425 int dst_w = dst.right - dst.left;
426 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800427 float w_scale = ((float)crop_w / (float)dst_w);
428 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530429 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700430
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800431 /* Workaround for MDP HW limitation in DSI command mode panels where
432 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
433 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530434 * There also is a HW limilation in MDP, minimum block size is 2x2
435 * Fallback to GPU if height is less than 2.
436 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700437 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800438 return false;
439
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800440 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530441 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800442 const float w_dscale = w_scale;
443 const float h_dscale = h_scale;
444
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800445 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700446
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530447 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700448 /* On targets that doesnt support Decimation (eg.,8x26)
449 * maximum downscale support is overlay pipe downscale.
450 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800451 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530452 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700453 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800454 return false;
455 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700456 // Decimation on macrotile format layers is not supported.
457 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530458 /* Bail out if
459 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700460 * 2. exceeds maximum downscale limit
461 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800462 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530463 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700464 w_dscale > maxMDPDownscale ||
465 h_dscale > maxMDPDownscale) {
466 return false;
467 }
468 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800469 return false;
470 }
471 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700472 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700473 return false;
474 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700475 }
476
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800477 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530478 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800479 const float w_uscale = 1.0f / w_scale;
480 const float h_uscale = 1.0f / h_scale;
481
482 if(w_uscale > upscale || h_uscale > upscale)
483 return false;
484 }
485
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800486 return true;
487}
488
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800489bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700490 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800491
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800492 if(!isEnabled()) {
493 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700494 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530495 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530496 qdutils::MDPVersion::getInstance().is8x16() ||
497 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800498 ctx->mVideoTransFlag &&
499 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700500 //1 Padding round to shift pipes across mixers
501 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
502 __FUNCTION__);
503 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700504 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
505 /* TODO: freeing up all the resources only for the targets having total
506 number of pipes < 8. Need to analyze number of VIG pipes used
507 for primary in previous draw cycle and accordingly decide
508 whether to fall back to full GPU comp or video only comp
509 */
510 if(isSecondaryConfiguring(ctx)) {
511 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
512 __FUNCTION__);
513 ret = false;
514 } else if(ctx->isPaddingRound) {
515 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
516 __FUNCTION__,mDpy);
517 ret = false;
518 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800519 } else if (ctx->isDMAStateChanging) {
520 // Bail out if a padding round has been invoked in order to switch DMA
521 // state to block mode. We need this to cater for the case when a layer
522 // requires rotation in the current frame.
523 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
524 __FUNCTION__);
525 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700526 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800527
Saurabh Shahaa236822013-04-24 18:07:26 -0700528 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800529}
530
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800531void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
532 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
533 fbRect = getIntersection(fbRect, roi);
534}
535
536/* 1) Identify layers that are not visible or lying outside the updating ROI and
537 * drop them from composition.
538 * 2) If we have a scaling layer which needs cropping against generated
539 * ROI, reset ROI to full resolution. */
540bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
541 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700542 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800543 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800544
545 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800546 if(!isValidRect(visibleRect)) {
547 mCurrentFrame.drop[i] = true;
548 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800549 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800550 }
551
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700552 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700553 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800554 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700555
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700556 if(!isValidRect(res)) {
557 mCurrentFrame.drop[i] = true;
558 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800559 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700560 /* Reset frame ROI when any layer which needs scaling also needs ROI
561 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800562 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800563 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700564 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
565 mCurrentFrame.dropCount = 0;
566 return false;
567 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800568
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800569 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530570 if (layer->blending == HWC_BLENDING_NONE &&
571 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800572 visibleRect = deductRect(visibleRect, res);
573 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700574 }
575 return true;
576}
577
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800578/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
579 * are updating. If DirtyRegion is applicable, calculate it by accounting all
580 * the changing layer's dirtyRegion. */
581void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
582 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700583 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800584 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700585 return;
586
587 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800588 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
589 (int)ctx->dpyAttr[mDpy].yres};
590
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700591 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800592 hwc_layer_1_t* layer = &list->hwLayers[index];
593 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800594 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700595 hwc_rect_t dst = layer->displayFrame;
596 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800597
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800598#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530599 if(!needsScaling(layer) && !layer->transform &&
600 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700601 {
602 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
603 int x_off = dst.left - src.left;
604 int y_off = dst.top - src.top;
605 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
606 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800607#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800608
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800609 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700610 }
611 }
612
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800613 /* No layer is updating. Still SF wants a refresh.*/
614 if(!isValidRect(roi))
615 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800616
617 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800618 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800619
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800620 ctx->listStats[mDpy].lRoi = roi;
621 if(!validateAndApplyROI(ctx, list))
622 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700623
624 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800625 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
626 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
627}
628
629void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
630 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
631 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
632
633 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
634 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
635 fbRect = getUnion(l_fbRect, r_fbRect);
636}
637/* 1) Identify layers that are not visible or lying outside BOTH the updating
638 * ROI's and drop them from composition. If a layer is spanning across both
639 * the halves of the screen but needed by only ROI, the non-contributing
640 * half will not be programmed for MDP.
641 * 2) If we have a scaling layer which needs cropping against generated
642 * ROI, reset ROI to full resolution. */
643bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
644 hwc_display_contents_1_t* list) {
645
646 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
647
648 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
649 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
650
651 for(int i = numAppLayers - 1; i >= 0; i--){
652 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
653 {
654 mCurrentFrame.drop[i] = true;
655 mCurrentFrame.dropCount++;
656 continue;
657 }
658
659 const hwc_layer_1_t* layer = &list->hwLayers[i];
660 hwc_rect_t dstRect = layer->displayFrame;
661
662 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
663 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
664 hwc_rect_t res = getUnion(l_res, r_res);
665
666 if(!isValidRect(l_res) && !isValidRect(r_res)) {
667 mCurrentFrame.drop[i] = true;
668 mCurrentFrame.dropCount++;
669 } else {
670 /* Reset frame ROI when any layer which needs scaling also needs ROI
671 * cropping */
672 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
673 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
674 mCurrentFrame.dropCount = 0;
675 return false;
676 }
677
radhakrishna4efbdd62014-11-03 13:19:27 +0530678 if (layer->blending == HWC_BLENDING_NONE &&
679 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800680 visibleRectL = deductRect(visibleRectL, l_res);
681 visibleRectR = deductRect(visibleRectR, r_res);
682 }
683 }
684 }
685 return true;
686}
687/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
688 * are updating. If DirtyRegion is applicable, calculate it by accounting all
689 * the changing layer's dirtyRegion. */
690void MDPCompSplit::generateROI(hwc_context_t *ctx,
691 hwc_display_contents_1_t* list) {
692 if(!canPartialUpdate(ctx, list))
693 return;
694
695 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
696 int lSplit = getLeftSplit(ctx, mDpy);
697
698 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
699 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
700
701 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
702 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
703
704 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
705 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
706
707 for(int index = 0; index < numAppLayers; index++ ) {
708 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800709 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800710 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800711 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700712 hwc_rect_t dst = layer->displayFrame;
713 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800714
715#ifdef QCOM_BSP
716 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700717 {
718 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
719 int x_off = dst.left - src.left;
720 int y_off = dst.top - src.top;
721 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
722 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800723#endif
724
725 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
726 if(isValidRect(l_dst))
727 l_roi = getUnion(l_roi, l_dst);
728
729 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
730 if(isValidRect(r_dst))
731 r_roi = getUnion(r_roi, r_dst);
732 }
733 }
734
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700735 /* For panels that cannot accept commands in both the interfaces, we cannot
736 * send two ROI's (for each half). We merge them into single ROI and split
737 * them across lSplit for MDP mixer use. The ROI's will be merged again
738 * finally before udpating the panel in the driver. */
739 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
740 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
741 l_roi = getIntersection(temp_roi, l_frame);
742 r_roi = getIntersection(temp_roi, r_frame);
743 }
744
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800745 /* No layer is updating. Still SF wants a refresh. */
746 if(!isValidRect(l_roi) && !isValidRect(r_roi))
747 return;
748
749 l_roi = getSanitizeROI(l_roi, l_frame);
750 r_roi = getSanitizeROI(r_roi, r_frame);
751
752 ctx->listStats[mDpy].lRoi = l_roi;
753 ctx->listStats[mDpy].rRoi = r_roi;
754
755 if(!validateAndApplyROI(ctx, list))
756 resetROI(ctx, mDpy);
757
758 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
759 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
760 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
761 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
762 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
763 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700764}
765
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800766/* Checks for conditions where all the layers marked for MDP comp cannot be
767 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800768bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800769 hwc_display_contents_1_t* list){
770
Saurabh Shahaa236822013-04-24 18:07:26 -0700771 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800772
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700773 // Fall back to video only composition, if AIV video mode is enabled
774 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700775 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
776 __FUNCTION__, mDpy);
777 return false;
778 }
779
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530780 /* No Idle fall back if secure display or secure RGB layers are present
781 * or if there is only a single layer being composed */
782 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
783 !ctx->listStats[mDpy].secureRGBCount &&
784 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700785 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
786 return false;
787 }
788
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800789 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700790 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
791 __FUNCTION__,
792 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800793 return false;
794 }
795
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700796 // if secondary is configuring or Padding round, fall back to video only
797 // composition and release all assigned non VIG pipes from primary.
798 if(isSecondaryConfiguring(ctx)) {
799 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
800 __FUNCTION__);
801 return false;
802 } else if(ctx->isPaddingRound) {
803 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
804 __FUNCTION__,mDpy);
805 return false;
806 }
807
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700808 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800809 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700810 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800811 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
812 return false;
813 }
814
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800815 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800816 hwc_layer_1_t* layer = &list->hwLayers[i];
817 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800818
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800819 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700820 if(!canUseRotator(ctx, mDpy)) {
821 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
822 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700823 return false;
824 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800825 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530826
827 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
828 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800829 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700830 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530831 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
832 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
833 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800834 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700835
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700836 if(ctx->mAD->isDoable()) {
837 return false;
838 }
839
Saurabh Shahaa236822013-04-24 18:07:26 -0700840 //If all above hard conditions are met we can do full or partial MDP comp.
841 bool ret = false;
842 if(fullMDPComp(ctx, list)) {
843 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700844 } else if(fullMDPCompWithPTOR(ctx, list)) {
845 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700846 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700847 ret = true;
848 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530849
Saurabh Shahaa236822013-04-24 18:07:26 -0700850 return ret;
851}
852
853bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700854
855 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
856 return false;
857
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700858 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
859 for(int i = 0; i < numAppLayers; i++) {
860 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700861 if(not mCurrentFrame.drop[i] and
862 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700863 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
864 return false;
865 }
866 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800867
Saurabh Shahaa236822013-04-24 18:07:26 -0700868 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700869 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
870 sizeof(mCurrentFrame.isFBComposed));
871 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
872 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700873
Raj Kamal389d6e32014-08-04 14:43:24 +0530874 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800875 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530876 }
877
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800878 if(!postHeuristicsHandling(ctx, list)) {
879 ALOGD_IF(isDebug(), "post heuristic handling failed");
880 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700881 return false;
882 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700883 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
884 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700885 return true;
886}
887
Sushil Chauhandefd3522014-05-13 18:17:12 -0700888/* Full MDP Composition with Peripheral Tiny Overlap Removal.
889 * MDP bandwidth limitations can be avoided, if the overlap region
890 * covered by the smallest layer at a higher z-order, gets composed
891 * by Copybit on a render buffer, which can be queued to MDP.
892 */
893bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
894 hwc_display_contents_1_t* list) {
895
896 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
897 const int stagesForMDP = min(sMaxPipesPerMixer,
898 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
899
900 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700901 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700902 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
903 return false;
904 }
905
906 // Frame level checks
907 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
908 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
909 isSecurePresent(ctx, mDpy)) {
910 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
911 return false;
912 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700913 // MDP comp checks
914 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700916 if(not isSupportedForMDPComp(ctx, layer)) {
917 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
918 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700919 }
920 }
921
Sushil Chauhandefd3522014-05-13 18:17:12 -0700922 /* We cannot use this composition mode, if:
923 1. A below layer needs scaling.
924 2. Overlap is not peripheral to display.
925 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700926 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700927 */
928
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700929 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
930 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
931 memset(overlapRect, 0, sizeof(overlapRect));
932 int layerPixelCount, minPixelCount = 0;
933 int numPTORLayersFound = 0;
934 for (int i = numAppLayers-1; (i >= 0 &&
935 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700936 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700937 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700938 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700939 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
940 // PTOR layer should be peripheral and cannot have transform
941 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
942 has90Transform(layer)) {
943 continue;
944 }
945 if((3 * (layerPixelCount + minPixelCount)) >
946 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
947 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
948 continue;
949 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700950 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700951 for (int j = i-1; j >= 0; j--) {
952 // Check if the layers below this layer qualifies for PTOR comp
953 hwc_layer_1_t* layer = &list->hwLayers[j];
954 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700955 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700957 if (isValidRect(getIntersection(dispFrame, disFrame))) {
958 if (has90Transform(layer) || needsScaling(layer)) {
959 found = false;
960 break;
961 }
962 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700963 }
964 }
965 // Store the minLayer Index
966 if(found) {
967 minLayerIndex[numPTORLayersFound] = i;
968 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
969 minPixelCount += layerPixelCount;
970 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700971 }
972 }
973
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700974 // No overlap layers
975 if (!numPTORLayersFound)
976 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700977
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700978 // Store the displayFrame and the sourceCrops of the layers
979 hwc_rect_t displayFrame[numAppLayers];
980 hwc_rect_t sourceCrop[numAppLayers];
981 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700982 hwc_layer_1_t* layer = &list->hwLayers[i];
983 displayFrame[i] = layer->displayFrame;
984 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700985 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700986
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530987 /**
988 * It's possible that 2 PTOR layers might have overlapping.
989 * In such case, remove the intersection(again if peripheral)
990 * from the lower PTOR layer to avoid overlapping.
991 * If intersection is not on peripheral then compromise
992 * by reducing number of PTOR layers.
993 **/
994 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
995 if(isValidRect(commonRect)) {
996 overlapRect[1] = deductRect(overlapRect[1], commonRect);
997 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
998 }
999
1000 ctx->mPtorInfo.count = numPTORLayersFound;
1001 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1002 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1003 }
1004
1005 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1006 // reset PTOR
1007 ctx->mPtorInfo.count = 0;
1008 if(isValidRect(commonRect)) {
1009 // If PTORs are intersecting restore displayframe of PTOR[1]
1010 // before returning, as we have modified it above.
1011 list->hwLayers[minLayerIndex[1]].displayFrame =
1012 displayFrame[minLayerIndex[1]];
1013 }
1014 return false;
1015 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001016 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1017 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1018
Xu Yangcda012c2014-07-30 21:57:21 +08001019 // Store the blending mode, planeAlpha, and transform of PTOR layers
1020 int32_t blending[numPTORLayersFound];
1021 uint8_t planeAlpha[numPTORLayersFound];
1022 uint32_t transform[numPTORLayersFound];
1023
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001024 for(int j = 0; j < numPTORLayersFound; j++) {
1025 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001026
1027 // Update src crop of PTOR layer
1028 hwc_layer_1_t* layer = &list->hwLayers[index];
1029 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1030 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1031 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1032 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1033
1034 // Store & update w, h, format of PTOR layer
1035 private_handle_t *hnd = (private_handle_t *)layer->handle;
1036 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1037 layerWhf[j] = whf;
1038 hnd->width = renderBuf->width;
1039 hnd->height = renderBuf->height;
1040 hnd->format = renderBuf->format;
1041
Xu Yangcda012c2014-07-30 21:57:21 +08001042 // Store & update blending mode, planeAlpha and transform of PTOR layer
1043 blending[j] = layer->blending;
1044 planeAlpha[j] = layer->planeAlpha;
1045 transform[j] = layer->transform;
1046 layer->blending = HWC_BLENDING_NONE;
1047 layer->planeAlpha = 0xFF;
1048 layer->transform = 0;
1049
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001050 // Remove overlap from crop & displayFrame of below layers
1051 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001052 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001053 if(!isValidRect(getIntersection(layer->displayFrame,
1054 overlapRect[j]))) {
1055 continue;
1056 }
1057 // Update layer attributes
1058 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1059 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301060 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001061 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1062 layer->transform);
1063 layer->sourceCropf.left = (float)srcCrop.left;
1064 layer->sourceCropf.top = (float)srcCrop.top;
1065 layer->sourceCropf.right = (float)srcCrop.right;
1066 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1067 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001068 }
1069
1070 mCurrentFrame.mdpCount = numAppLayers;
1071 mCurrentFrame.fbCount = 0;
1072 mCurrentFrame.fbZ = -1;
1073
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301074 for (int j = 0; j < numAppLayers; j++) {
1075 if(isValidRect(list->hwLayers[j].displayFrame)) {
1076 mCurrentFrame.isFBComposed[j] = false;
1077 } else {
1078 mCurrentFrame.mdpCount--;
1079 mCurrentFrame.drop[j] = true;
1080 }
1081 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001082
1083 bool result = postHeuristicsHandling(ctx, list);
1084
1085 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001086 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001087 hwc_layer_1_t* layer = &list->hwLayers[i];
1088 layer->displayFrame = displayFrame[i];
1089 layer->sourceCropf.left = (float)sourceCrop[i].left;
1090 layer->sourceCropf.top = (float)sourceCrop[i].top;
1091 layer->sourceCropf.right = (float)sourceCrop[i].right;
1092 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1093 }
1094
Xu Yangcda012c2014-07-30 21:57:21 +08001095 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001096 for (int i = 0; i < numPTORLayersFound; i++) {
1097 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001098 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001099 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1100 hnd->width = layerWhf[i].w;
1101 hnd->height = layerWhf[i].h;
1102 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001103 layer->blending = blending[i];
1104 layer->planeAlpha = planeAlpha[i];
1105 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001106 }
1107
Sushil Chauhandefd3522014-05-13 18:17:12 -07001108 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001109 // reset PTOR
1110 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001111 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001112 } else {
1113 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1114 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001115 }
1116
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001117 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1118 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001119 return result;
1120}
1121
Saurabh Shahaa236822013-04-24 18:07:26 -07001122bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1123{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001124 if(!sEnableMixedMode) {
1125 //Mixed mode is disabled. No need to even try caching.
1126 return false;
1127 }
1128
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001129 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001130 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001131 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001132 cacheBasedComp(ctx, list);
1133 } else {
1134 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001135 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001136 }
1137
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001138 return ret;
1139}
1140
1141bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1142 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001143 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1144 return false;
1145
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001146 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001147 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001148 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001149
1150 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1151 for(int i = 0; i < numAppLayers; i++) {
1152 if(!mCurrentFrame.isFBComposed[i]) {
1153 hwc_layer_1_t* layer = &list->hwLayers[i];
1154 if(not isSupportedForMDPComp(ctx, layer)) {
1155 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1156 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001157 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001158 return false;
1159 }
1160 }
1161 }
1162
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001163 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001164 /* mark secure RGB layers for MDP comp */
1165 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301166 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001167 if(!ret) {
1168 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001169 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001170 return false;
1171 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001172
1173 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001174
Raj Kamal389d6e32014-08-04 14:43:24 +05301175 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001176 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301177 }
1178
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001179 if(!postHeuristicsHandling(ctx, list)) {
1180 ALOGD_IF(isDebug(), "post heuristic handling failed");
1181 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001182 return false;
1183 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001184 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1185 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001186
Saurabh Shahaa236822013-04-24 18:07:26 -07001187 return true;
1188}
1189
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001190bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001191 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001192 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1193 return false;
1194
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001195 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001196 return false;
1197 }
1198
Saurabh Shahb772ae32013-11-18 15:40:02 -08001199 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001200 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1201 const int stagesForMDP = min(sMaxPipesPerMixer,
1202 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001203
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001204 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1205 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1206 int lastMDPSupportedIndex = numAppLayers;
1207 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001208
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001209 //Find the minimum MDP batch size
1210 for(int i = 0; i < numAppLayers;i++) {
1211 if(mCurrentFrame.drop[i]) {
1212 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001213 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001214 }
1215 hwc_layer_1_t* layer = &list->hwLayers[i];
1216 if(not isSupportedForMDPComp(ctx, layer)) {
1217 lastMDPSupportedIndex = i;
1218 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1219 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001220 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001221 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001222 }
1223
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001224 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1225 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1226 mCurrentFrame.dropCount);
1227
1228 //Start at a point where the fb batch should at least have 2 layers, for
1229 //this mode to be justified.
1230 while(fbBatchSize < 2) {
1231 ++fbBatchSize;
1232 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001233 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001234
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001235 //If there are no layers for MDP, this mode doesnt make sense.
1236 if(mdpBatchSize < 1) {
1237 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1238 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001239 return false;
1240 }
1241
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001242 mCurrentFrame.reset(numAppLayers);
1243
1244 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1245 while(mdpBatchSize > 0) {
1246 //Mark layers for MDP comp
1247 int mdpBatchLeft = mdpBatchSize;
1248 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1249 if(mCurrentFrame.drop[i]) {
1250 continue;
1251 }
1252 mCurrentFrame.isFBComposed[i] = false;
1253 --mdpBatchLeft;
1254 }
1255
1256 mCurrentFrame.fbZ = mdpBatchSize;
1257 mCurrentFrame.fbCount = fbBatchSize;
1258 mCurrentFrame.mdpCount = mdpBatchSize;
1259
1260 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1261 __FUNCTION__, mdpBatchSize, fbBatchSize,
1262 mCurrentFrame.dropCount);
1263
1264 if(postHeuristicsHandling(ctx, list)) {
1265 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001266 __FUNCTION__);
1267 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1268 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001269 return true;
1270 }
1271
1272 reset(ctx);
1273 --mdpBatchSize;
1274 ++fbBatchSize;
1275 }
1276
1277 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001278}
1279
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001280bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301281 if(mDpy or isSecurePresent(ctx, mDpy) or
1282 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001283 return false;
1284 }
1285 return true;
1286}
1287
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001288bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1289 hwc_display_contents_1_t* list){
1290 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1291 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001292 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001293 return false;
1294 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001295 if(ctx->listStats[mDpy].secureUI)
1296 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001297 return true;
1298}
1299
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001300bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1301 hwc_display_contents_1_t* list) {
1302 const bool secureOnly = true;
1303 return videoOnlyComp(ctx, list, not secureOnly) or
1304 videoOnlyComp(ctx, list, secureOnly);
1305}
1306
1307bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001308 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001309 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1310 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301311
Saurabh Shahaa236822013-04-24 18:07:26 -07001312 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301313 if(!isSecurePresent(ctx, mDpy)) {
1314 /* Bail out if we are processing only secured video layers
1315 * and we dont have any */
1316 if(secureOnly) {
1317 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1318 return false;
1319 }
1320 /* No Idle fall back for secure video layers and if there is only
1321 * single layer being composed. */
1322 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1323 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1324 return false;
1325 }
1326 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001327
Saurabh Shahaa236822013-04-24 18:07:26 -07001328 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001329 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001330 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001331 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001332
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001333 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1334 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001335 return false;
1336 }
1337
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001338 if(mCurrentFrame.fbCount)
1339 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001340
Raj Kamal389d6e32014-08-04 14:43:24 +05301341 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001342 adjustForSourceSplit(ctx, list);
1343 }
1344
1345 if(!postHeuristicsHandling(ctx, list)) {
1346 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301347 if(errno == ENOBUFS) {
1348 ALOGD_IF(isDebug(), "SMP Allocation failed");
1349 //On SMP allocation failure in video only comp add padding round
1350 ctx->isPaddingRound = true;
1351 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001352 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001353 return false;
1354 }
1355
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001356 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1357 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001358 return true;
1359}
1360
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001361/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1362bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1363 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001364 // Fall back to video only composition, if AIV video mode is enabled
1365 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001366 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1367 __FUNCTION__, mDpy);
1368 return false;
1369 }
1370
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001371 const bool secureOnly = true;
1372 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1373 mdpOnlyLayersComp(ctx, list, secureOnly);
1374
1375}
1376
1377bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1378 hwc_display_contents_1_t* list, bool secureOnly) {
1379
1380 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1381 return false;
1382
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301383 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1384 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1385 /* Bail out if we are processing only secured video/ui layers
1386 * and we dont have any */
1387 if(secureOnly) {
1388 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1389 return false;
1390 }
1391 /* No Idle fall back for secure video/ui layers and if there is only
1392 * single layer being composed. */
1393 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1394 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1395 return false;
1396 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001397 }
1398
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001399 /* Bail out if we dont have any secure RGB layers */
1400 if (!ctx->listStats[mDpy].secureRGBCount) {
1401 reset(ctx);
1402 return false;
1403 }
1404
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001405 mCurrentFrame.reset(numAppLayers);
1406 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1407
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001408 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001409 /* mark secure RGB layers for MDP comp */
1410 updateSecureRGB(ctx, list);
1411
1412 if(mCurrentFrame.mdpCount == 0) {
1413 reset(ctx);
1414 return false;
1415 }
1416
1417 /* find the maximum batch of layers to be marked for framebuffer */
1418 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1419 if(!ret) {
1420 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1421 reset(ctx);
1422 return false;
1423 }
1424
1425 if(sEnableYUVsplit){
1426 adjustForSourceSplit(ctx, list);
1427 }
1428
1429 if(!postHeuristicsHandling(ctx, list)) {
1430 ALOGD_IF(isDebug(), "post heuristic handling failed");
1431 reset(ctx);
1432 return false;
1433 }
1434
1435 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1436 __FUNCTION__);
1437 return true;
1438}
1439
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001440/* Checks for conditions where YUV layers cannot be bypassed */
1441bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001442 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001443 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001444 return false;
1445 }
1446
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001447 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001448 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1449 return false;
1450 }
1451
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001452 if(isSecuring(ctx, layer)) {
1453 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1454 return false;
1455 }
1456
Saurabh Shah4fdde762013-04-30 18:47:33 -07001457 if(!isValidDimension(ctx, layer)) {
1458 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1459 __FUNCTION__);
1460 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001461 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001462
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001463 if(layer->planeAlpha < 0xFF) {
1464 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1465 in video only mode",
1466 __FUNCTION__);
1467 return false;
1468 }
1469
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001470 return true;
1471}
1472
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001473/* Checks for conditions where Secure RGB layers cannot be bypassed */
1474bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1475 if(isSkipLayer(layer)) {
1476 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1477 __FUNCTION__, mDpy);
1478 return false;
1479 }
1480
1481 if(isSecuring(ctx, layer)) {
1482 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1483 return false;
1484 }
1485
1486 if(not isSupportedForMDPComp(ctx, layer)) {
1487 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1488 __FUNCTION__);
1489 return false;
1490 }
1491 return true;
1492}
1493
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301494/* starts at fromIndex and check for each layer to find
1495 * if it it has overlapping with any Updating layer above it in zorder
1496 * till the end of the batch. returns true if it finds any intersection */
1497bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1498 int fromIndex, int toIndex) {
1499 for(int i = fromIndex; i < toIndex; i++) {
1500 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1501 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1502 return false;
1503 }
1504 }
1505 }
1506 return true;
1507}
1508
1509/* Checks if given layer at targetLayerIndex has any
1510 * intersection with all the updating layers in beween
1511 * fromIndex and toIndex. Returns true if it finds intersectiion */
1512bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1513 int fromIndex, int toIndex, int targetLayerIndex) {
1514 for(int i = fromIndex; i <= toIndex; i++) {
1515 if(!mCurrentFrame.isFBComposed[i]) {
1516 if(areLayersIntersecting(&list->hwLayers[i],
1517 &list->hwLayers[targetLayerIndex])) {
1518 return true;
1519 }
1520 }
1521 }
1522 return false;
1523}
1524
1525int MDPComp::getBatch(hwc_display_contents_1_t* list,
1526 int& maxBatchStart, int& maxBatchEnd,
1527 int& maxBatchCount) {
1528 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301529 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001530 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301531 while (i < mCurrentFrame.layerCount) {
1532 int batchCount = 0;
1533 int batchStart = i;
1534 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001535 /* Adjust batch Z order with the dropped layers so far */
1536 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301537 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301538 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301539 while(i < mCurrentFrame.layerCount) {
1540 if(!mCurrentFrame.isFBComposed[i]) {
1541 if(!batchCount) {
1542 i++;
1543 break;
1544 }
1545 updatingLayersAbove++;
1546 i++;
1547 continue;
1548 } else {
1549 if(mCurrentFrame.drop[i]) {
1550 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001551 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301552 continue;
1553 } else if(updatingLayersAbove <= 0) {
1554 batchCount++;
1555 batchEnd = i;
1556 i++;
1557 continue;
1558 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1559
1560 // We have a valid updating layer already. If layer-i not
1561 // have overlapping with all updating layers in between
1562 // batch-start and i, then we can add layer i to batch.
1563 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1564 batchCount++;
1565 batchEnd = i;
1566 i++;
1567 continue;
1568 } else if(canPushBatchToTop(list, batchStart, i)) {
1569 //If All the non-updating layers with in this batch
1570 //does not have intersection with the updating layers
1571 //above in z-order, then we can safely move the batch to
1572 //higher z-order. Increment fbZ as it is moving up.
1573 if( firstZReverseIndex < 0) {
1574 firstZReverseIndex = i;
1575 }
1576 batchCount++;
1577 batchEnd = i;
1578 fbZ += updatingLayersAbove;
1579 i++;
1580 updatingLayersAbove = 0;
1581 continue;
1582 } else {
1583 //both failed.start the loop again from here.
1584 if(firstZReverseIndex >= 0) {
1585 i = firstZReverseIndex;
1586 }
1587 break;
1588 }
1589 }
1590 }
1591 }
1592 if(batchCount > maxBatchCount) {
1593 maxBatchCount = batchCount;
1594 maxBatchStart = batchStart;
1595 maxBatchEnd = batchEnd;
1596 fbZOrder = fbZ;
1597 }
1598 }
1599 return fbZOrder;
1600}
1601
1602bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1603 hwc_display_contents_1_t* list) {
1604 /* Idea is to keep as many non-updating(cached) layers in FB and
1605 * send rest of them through MDP. This is done in 2 steps.
1606 * 1. Find the maximum contiguous batch of non-updating layers.
1607 * 2. See if we can improve this batch size for caching by adding
1608 * opaque layers around the batch, if they don't have
1609 * any overlapping with the updating layers in between.
1610 * NEVER mark an updating layer for caching.
1611 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612
1613 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001614 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001615 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301616 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001617
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001618 /* Nothing is cached. No batching needed */
1619 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001620 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001621 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001622
1623 /* No MDP comp layers, try to use other comp modes */
1624 if(mCurrentFrame.mdpCount == 0) {
1625 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001626 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301628 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001629
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301630 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001631 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001632 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001633 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301634 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001635 if(!mCurrentFrame.drop[i]){
1636 //If an unsupported layer is being attempted to
1637 //be pulled out we should fail
1638 if(not isSupportedForMDPComp(ctx, layer)) {
1639 return false;
1640 }
1641 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001642 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643 }
1644 }
1645
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301646 // update the frame data
1647 mCurrentFrame.fbZ = fbZ;
1648 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001649 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001650 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001651
1652 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301653 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001654
1655 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001657
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001659 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001661 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001663 for(int i = 0; i < numAppLayers; i++) {
1664 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001665 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001666 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001667 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001668 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001669 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 }
1671 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001672
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001673 frame.fbCount = fbCount;
1674 frame.mdpCount = frame.layerCount - frame.fbCount
1675 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001676
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001677 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1678 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001679}
1680
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001681// drop other non-AIV layers from external display list.
1682void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001683 hwc_display_contents_1_t* list) {
1684 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1685 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001686 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001687 mCurrentFrame.dropCount++;
1688 mCurrentFrame.drop[i] = true;
1689 }
1690 }
1691 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1692 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1693 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1694 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1695 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1696 mCurrentFrame.dropCount);
1697}
1698
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001699void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001700 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001701 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1702 for(int index = 0;index < nYuvCount; index++){
1703 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1704 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1705
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001706 if(mCurrentFrame.drop[nYuvIndex]) {
1707 continue;
1708 }
1709
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001711 if(!frame.isFBComposed[nYuvIndex]) {
1712 frame.isFBComposed[nYuvIndex] = true;
1713 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001714 }
1715 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001716 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001717 private_handle_t *hnd = (private_handle_t *)layer->handle;
1718 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001719 frame.isFBComposed[nYuvIndex] = false;
1720 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001721 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001722 }
1723 }
1724 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001725
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001726 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1727 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001728}
1729
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001730void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1731 hwc_display_contents_1_t* list) {
1732 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1733 for(int index = 0;index < nSecureRGBCount; index++){
1734 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1735 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1736
1737 if(!isSecureRGBDoable(ctx, layer)) {
1738 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1739 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1740 mCurrentFrame.fbCount++;
1741 }
1742 } else {
1743 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1744 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1745 mCurrentFrame.fbCount--;
1746 }
1747 }
1748 }
1749
1750 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1751 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1752 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1753 mCurrentFrame.fbCount);
1754}
1755
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001756hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1757 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001758 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001759
1760 /* Update only the region of FB needed for composition */
1761 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1762 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1763 hwc_layer_1_t* layer = &list->hwLayers[i];
1764 hwc_rect_t dst = layer->displayFrame;
1765 fbRect = getUnion(fbRect, dst);
1766 }
1767 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001768 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001769 return fbRect;
1770}
1771
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001772bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1773 hwc_display_contents_1_t* list) {
1774
1775 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001776 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001777 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1778 return false;
1779 }
1780
1781 //Limitations checks
1782 if(!hwLimitationsCheck(ctx, list)) {
1783 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1784 return false;
1785 }
1786
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001787 //Configure framebuffer first if applicable
1788 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001789 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001790 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1791 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001792 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1793 __FUNCTION__);
1794 return false;
1795 }
1796 }
1797
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001798 mCurrentFrame.map();
1799
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001800 if(!allocLayerPipes(ctx, list)) {
1801 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001802 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001803 }
1804
1805 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001806 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001807 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001808 int mdpIndex = mCurrentFrame.layerToMDP[index];
1809 hwc_layer_1_t* layer = &list->hwLayers[index];
1810
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301811 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1812 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1813 mdpNextZOrder++;
1814 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001815 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1816 cur_pipe->zOrder = mdpNextZOrder++;
1817
radhakrishnac9a67412013-09-25 17:40:42 +05301818 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301819 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301820 if(configure4k2kYuv(ctx, layer,
1821 mCurrentFrame.mdpToLayer[mdpIndex])
1822 != 0 ){
1823 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1824 for layer %d",__FUNCTION__, index);
1825 return false;
1826 }
1827 else{
1828 mdpNextZOrder++;
1829 }
1830 continue;
1831 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001832 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1833 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301834 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001835 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001836 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001837 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001838 }
1839
Saurabh Shaha36be922013-12-16 18:18:39 -08001840 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1841 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1842 ,__FUNCTION__, mDpy);
1843 return false;
1844 }
1845
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001846 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001847 return true;
1848}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001849
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001850bool MDPComp::resourceCheck(hwc_context_t* ctx,
1851 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001852 const bool fbUsed = mCurrentFrame.fbCount;
1853 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1854 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1855 return false;
1856 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001857
1858 //Will benefit cases where a video has non-updating background.
1859 if((mDpy > HWC_DISPLAY_PRIMARY) and
1860 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1861 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1862 return false;
1863 }
1864
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001865 // Init rotCount to number of rotate sessions used by other displays
1866 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1867 // Count the number of rotator sessions required for current display
1868 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1869 if(!mCurrentFrame.isFBComposed[index]) {
1870 hwc_layer_1_t* layer = &list->hwLayers[index];
1871 private_handle_t *hnd = (private_handle_t *)layer->handle;
1872 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1873 rotCount++;
1874 }
1875 }
1876 }
1877 // if number of layers to rotate exceeds max rotator sessions, bail out.
1878 if(rotCount > RotMgr::MAX_ROT_SESS) {
1879 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1880 __FUNCTION__, mDpy);
1881 return false;
1882 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001883 return true;
1884}
1885
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301886bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1887 hwc_display_contents_1_t* list) {
1888
1889 //A-family hw limitation:
1890 //If a layer need alpha scaling, MDP can not support.
1891 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1892 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1893 if(!mCurrentFrame.isFBComposed[i] &&
1894 isAlphaScaled( &list->hwLayers[i])) {
1895 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1896 return false;
1897 }
1898 }
1899 }
1900
1901 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1902 //If multiple layers requires downscaling and also they are overlapping
1903 //fall back to GPU since MDSS can not handle it.
1904 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1905 qdutils::MDPVersion::getInstance().is8x26()) {
1906 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1907 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1908 if(!mCurrentFrame.isFBComposed[i] &&
1909 isDownscaleRequired(botLayer)) {
1910 //if layer-i is marked for MDP and needs downscaling
1911 //check if any MDP layer on top of i & overlaps with layer-i
1912 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1913 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1914 if(!mCurrentFrame.isFBComposed[j] &&
1915 isDownscaleRequired(topLayer)) {
1916 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1917 topLayer->displayFrame);
1918 if(isValidRect(r))
1919 return false;
1920 }
1921 }
1922 }
1923 }
1924 }
1925 return true;
1926}
1927
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001928// Checks only if videos or single layer(RGB) is updating
1929// which is used for setting dynamic fps or perf hint for single
1930// layer video playback
1931bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1932 hwc_display_contents_1_t* list) {
1933 bool support = false;
1934 FrameInfo frame;
1935 frame.reset(mCurrentFrame.layerCount);
1936 memset(&frame.drop, 0, sizeof(frame.drop));
1937 frame.dropCount = 0;
1938 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1939 updateLayerCache(ctx, list, frame);
1940 updateYUV(ctx, list, false /*secure only*/, frame);
1941 // There are only updating YUV layers or there is single RGB
1942 // Layer(Youtube)
1943 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1944 (frame.layerCount == 1)) {
1945 support = true;
1946 }
1947 return support;
1948}
1949
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301950void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1951 //For primary display, set the dynamic refreshrate
1952 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1953 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301954 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1955 MDPVersion& mdpHw = MDPVersion::getInstance();
1956 if(sIdleFallBack) {
1957 //Set minimum panel refresh rate during idle timeout
1958 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001959 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301960 //Set the new fresh rate, if there is only one updating YUV layer
1961 //or there is one single RGB layer with this request
1962 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1963 }
1964 setRefreshRate(ctx, mDpy, refreshRate);
1965 }
1966}
1967
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001968int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001969 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001970 char property[PROPERTY_VALUE_MAX];
1971
Raj Kamal4393eaa2014-06-06 13:45:20 +05301972 if(!ctx || !list) {
1973 ALOGE("%s: Invalid context or list",__FUNCTION__);
1974 mCachedFrame.reset();
1975 return -1;
1976 }
1977
1978 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001979 if(mDpy == HWC_DISPLAY_PRIMARY) {
1980 sSimulationFlags = 0;
1981 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1982 int currentFlags = atoi(property);
1983 if(currentFlags != sSimulationFlags) {
1984 sSimulationFlags = currentFlags;
1985 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1986 sSimulationFlags, sSimulationFlags);
1987 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001988 }
1989 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001990 // reset PTOR
1991 if(!mDpy)
1992 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001993
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301994 //reset old data
1995 mCurrentFrame.reset(numLayers);
1996 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1997 mCurrentFrame.dropCount = 0;
1998
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301999 //Do not cache the information for next draw cycle.
2000 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2001 ALOGI("%s: Unsupported layer count for mdp composition",
2002 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002003 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302004#ifdef DYNAMIC_FPS
2005 setDynRefreshRate(ctx, list);
2006#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002007 return -1;
2008 }
2009
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002010 // Detect the start of animation and fall back to GPU only once to cache
2011 // all the layers in FB and display FB content untill animation completes.
2012 if(ctx->listStats[mDpy].isDisplayAnimating) {
2013 mCurrentFrame.needsRedraw = false;
2014 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2015 mCurrentFrame.needsRedraw = true;
2016 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2017 }
2018 setMDPCompLayerFlags(ctx, list);
2019 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302020#ifdef DYNAMIC_FPS
2021 setDynRefreshRate(ctx, list);
2022#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002023 ret = -1;
2024 return ret;
2025 } else {
2026 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2027 }
2028
Saurabh Shahb39f8152013-08-22 10:21:44 -07002029 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002030 if(isFrameDoable(ctx)) {
2031 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002032 // if AIV Video mode is enabled, drop all non AIV layers from the
2033 // external display list.
2034 if(ctx->listStats[mDpy].mAIVVideoMode) {
2035 dropNonAIVLayers(ctx, list);
2036 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002037
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002038 // if tryFullFrame fails, try to push all video and secure RGB layers
2039 // to MDP for composition.
2040 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002041 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302042 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002043 setMDPCompLayerFlags(ctx, list);
2044 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002045 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002046 reset(ctx);
2047 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2048 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002049 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002050 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2051 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002052 }
2053 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302054 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2055 enablePartialUpdateForMDP3) {
2056 generateROI(ctx, list);
2057 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2058 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2059 }
2060 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002061 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2062 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002063 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002064 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002065
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002066 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002067 ALOGD("GEOMETRY change: %d",
2068 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002069 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002070 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002071 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002072 }
2073
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002074#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302075 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002076#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002077 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002078
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002079 mCachedFrame.cacheAll(list);
2080 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002081 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002082}
2083
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002084bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302085
2086 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302087 int mdpIndex = mCurrentFrame.layerToMDP[index];
2088 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2089 info.pipeInfo = new MdpYUVPipeInfo;
2090 info.rot = NULL;
2091 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302092
2093 pipe_info.lIndex = ovutils::OV_INVALID;
2094 pipe_info.rIndex = ovutils::OV_INVALID;
2095
Saurabh Shahc62f3982014-03-05 14:28:26 -08002096 Overlay::PipeSpecs pipeSpecs;
2097 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2098 pipeSpecs.needsScaling = true;
2099 pipeSpecs.dpy = mDpy;
2100 pipeSpecs.fb = false;
2101
2102 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302103 if(pipe_info.lIndex == ovutils::OV_INVALID){
2104 bRet = false;
2105 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2106 __FUNCTION__);
2107 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002108 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302109 if(pipe_info.rIndex == ovutils::OV_INVALID){
2110 bRet = false;
2111 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2112 __FUNCTION__);
2113 }
2114 return bRet;
2115}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002116
2117int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2118 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002119 if (ctx->mPtorInfo.isActive()) {
2120 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002121 if (fd < 0) {
2122 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002123 }
2124 }
2125 return fd;
2126}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002127//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002128
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002129void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302130 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002131 //If 4k2k Yuv layer split is possible, and if
2132 //fbz is above 4k2k layer, increment fb zorder by 1
2133 //as we split 4k2k layer and increment zorder for right half
2134 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002135 if(!ctx)
2136 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002137 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302138 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2139 index++) {
2140 if(!mCurrentFrame.isFBComposed[index]) {
2141 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2142 mdpNextZOrder++;
2143 }
2144 mdpNextZOrder++;
2145 hwc_layer_1_t* layer = &list->hwLayers[index];
2146 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302147 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302148 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2149 mCurrentFrame.fbZ += 1;
2150 mdpNextZOrder++;
2151 //As we split 4kx2k yuv layer and program to 2 VG pipes
2152 //(if available) increase mdpcount by 1.
2153 mCurrentFrame.mdpCount++;
2154 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002155 }
2156 }
2157 }
radhakrishnac9a67412013-09-25 17:40:42 +05302158}
2159
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002160/*
2161 * Configures pipe(s) for MDP composition
2162 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002163int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002164 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002165 MdpPipeInfoNonSplit& mdp_info =
2166 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302167 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002168 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002169 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002170
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002171 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2172 __FUNCTION__, layer, zOrder, dest);
2173
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002174 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002175 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002176}
2177
Saurabh Shah88e4d272013-09-03 13:31:29 -07002178bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002179 hwc_display_contents_1_t* list) {
2180 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002181
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002182 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002183
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002184 hwc_layer_1_t* layer = &list->hwLayers[index];
2185 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302186 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002187 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302188 continue;
2189 }
2190 }
2191
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002192 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002193 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002194 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002195 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002196 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002197
Saurabh Shahc62f3982014-03-05 14:28:26 -08002198 Overlay::PipeSpecs pipeSpecs;
2199 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2200 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2201 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2202 (qdutils::MDPVersion::getInstance().is8x26() and
2203 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2204 pipeSpecs.dpy = mDpy;
2205 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002206 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002207
Saurabh Shahc62f3982014-03-05 14:28:26 -08002208 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2209
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002210 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002211 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002212 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002213 }
2214 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002215 return true;
2216}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002217
radhakrishnac9a67412013-09-25 17:40:42 +05302218int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2219 PipeLayerPair& PipeLayerPair) {
2220 MdpYUVPipeInfo& mdp_info =
2221 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2222 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302223 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302224 eDest lDest = mdp_info.lIndex;
2225 eDest rDest = mdp_info.rIndex;
2226
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002227 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302228 lDest, rDest, &PipeLayerPair.rot);
2229}
2230
Saurabh Shah88e4d272013-09-03 13:31:29 -07002231bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002232
Raj Kamal4393eaa2014-06-06 13:45:20 +05302233 if(!isEnabled() or !mModeOn) {
2234 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302235 return true;
2236 }
2237
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002238 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002239 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002240 sHandleTimeout = true;
2241 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002242
2243 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002244 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002245
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002246 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2247 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002248 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002249 if(mCurrentFrame.isFBComposed[i]) continue;
2250
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002251 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002252 private_handle_t *hnd = (private_handle_t *)layer->handle;
2253 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002254 if (!(layer->flags & HWC_COLOR_FILL)) {
2255 ALOGE("%s handle null", __FUNCTION__);
2256 return false;
2257 }
2258 // No PLAY for Color layer
2259 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2260 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002261 }
2262
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002263 int mdpIndex = mCurrentFrame.layerToMDP[i];
2264
Raj Kamal389d6e32014-08-04 14:43:24 +05302265 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302266 {
2267 MdpYUVPipeInfo& pipe_info =
2268 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2269 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2270 ovutils::eDest indexL = pipe_info.lIndex;
2271 ovutils::eDest indexR = pipe_info.rIndex;
2272 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302273 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302274 if(rot) {
2275 rot->queueBuffer(fd, offset);
2276 fd = rot->getDstMemId();
2277 offset = rot->getDstOffset();
2278 }
2279 if(indexL != ovutils::OV_INVALID) {
2280 ovutils::eDest destL = (ovutils::eDest)indexL;
2281 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2282 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2283 if (!ov.queueBuffer(fd, offset, destL)) {
2284 ALOGE("%s: queueBuffer failed for display:%d",
2285 __FUNCTION__, mDpy);
2286 return false;
2287 }
2288 }
2289
2290 if(indexR != ovutils::OV_INVALID) {
2291 ovutils::eDest destR = (ovutils::eDest)indexR;
2292 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2293 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2294 if (!ov.queueBuffer(fd, offset, destR)) {
2295 ALOGE("%s: queueBuffer failed for display:%d",
2296 __FUNCTION__, mDpy);
2297 return false;
2298 }
2299 }
2300 }
2301 else{
2302 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002303 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302304 ovutils::eDest dest = pipe_info.index;
2305 if(dest == ovutils::OV_INVALID) {
2306 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002307 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302308 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002309
radhakrishnac9a67412013-09-25 17:40:42 +05302310 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2311 continue;
2312 }
2313
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002314 int fd = hnd->fd;
2315 uint32_t offset = (uint32_t)hnd->offset;
2316 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2317 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002318 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002319 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002320 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002321 }
2322
radhakrishnac9a67412013-09-25 17:40:42 +05302323 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2324 using pipe: %d", __FUNCTION__, layer,
2325 hnd, dest );
2326
radhakrishnac9a67412013-09-25 17:40:42 +05302327 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2328 if(rot) {
2329 if(!rot->queueBuffer(fd, offset))
2330 return false;
2331 fd = rot->getDstMemId();
2332 offset = rot->getDstOffset();
2333 }
2334
2335 if (!ov.queueBuffer(fd, offset, dest)) {
2336 ALOGE("%s: queueBuffer failed for display:%d ",
2337 __FUNCTION__, mDpy);
2338 return false;
2339 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002340 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002341
2342 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002343 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002344 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002345}
2346
Saurabh Shah88e4d272013-09-03 13:31:29 -07002347//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002348
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002349void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302350 hwc_display_contents_1_t* list){
2351 //if 4kx2k yuv layer is totally present in either in left half
2352 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302353 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302354 if(mCurrentFrame.fbZ >= 0) {
2355 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2356 index++) {
2357 if(!mCurrentFrame.isFBComposed[index]) {
2358 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2359 mdpNextZOrder++;
2360 }
2361 mdpNextZOrder++;
2362 hwc_layer_1_t* layer = &list->hwLayers[index];
2363 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302364 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302365 hwc_rect_t dst = layer->displayFrame;
2366 if((dst.left > lSplit) || (dst.right < lSplit)) {
2367 mCurrentFrame.mdpCount += 1;
2368 }
2369 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2370 mCurrentFrame.fbZ += 1;
2371 mdpNextZOrder++;
2372 }
2373 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002374 }
radhakrishnac9a67412013-09-25 17:40:42 +05302375 }
2376}
2377
Saurabh Shah88e4d272013-09-03 13:31:29 -07002378bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002379 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002380
Saurabh Shahc62f3982014-03-05 14:28:26 -08002381 const int lSplit = getLeftSplit(ctx, mDpy);
2382 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002383 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002384 pipe_info.lIndex = ovutils::OV_INVALID;
2385 pipe_info.rIndex = ovutils::OV_INVALID;
2386
Saurabh Shahc62f3982014-03-05 14:28:26 -08002387 Overlay::PipeSpecs pipeSpecs;
2388 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2389 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2390 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2391 pipeSpecs.dpy = mDpy;
2392 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2393 pipeSpecs.fb = false;
2394
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002395 // Acquire pipe only for the updating half
2396 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2397 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2398
2399 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002400 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002401 if(pipe_info.lIndex == ovutils::OV_INVALID)
2402 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002403 }
2404
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002405 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002406 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2407 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002408 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002409 return false;
2410 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002411
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002412 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002413}
2414
Saurabh Shah88e4d272013-09-03 13:31:29 -07002415bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002416 hwc_display_contents_1_t* list) {
2417 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002418
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002419 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002420
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002421 hwc_layer_1_t* layer = &list->hwLayers[index];
2422 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302423 hwc_rect_t dst = layer->displayFrame;
2424 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302425 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302426 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002427 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302428 continue;
2429 }
2430 }
2431 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002432 int mdpIndex = mCurrentFrame.layerToMDP[index];
2433 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002434 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002435 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002436 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002437
Saurabh Shahc62f3982014-03-05 14:28:26 -08002438 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2439 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2440 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002441 return false;
2442 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002443 }
2444 return true;
2445}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002446
radhakrishnac9a67412013-09-25 17:40:42 +05302447int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2448 PipeLayerPair& PipeLayerPair) {
2449 const int lSplit = getLeftSplit(ctx, mDpy);
2450 hwc_rect_t dst = layer->displayFrame;
2451 if((dst.left > lSplit)||(dst.right < lSplit)){
2452 MdpYUVPipeInfo& mdp_info =
2453 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2454 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302455 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302456 eDest lDest = mdp_info.lIndex;
2457 eDest rDest = mdp_info.rIndex;
2458
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002459 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302460 lDest, rDest, &PipeLayerPair.rot);
2461 }
2462 else{
2463 return configure(ctx, layer, PipeLayerPair);
2464 }
2465}
2466
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002467/*
2468 * Configures pipe(s) for MDP composition
2469 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002470int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002471 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002472 MdpPipeInfoSplit& mdp_info =
2473 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002474 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302475 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002476 eDest lDest = mdp_info.lIndex;
2477 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002478
2479 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002480 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002481
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002482 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002483 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002484}
2485
Saurabh Shah88e4d272013-09-03 13:31:29 -07002486bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002487
Raj Kamal4393eaa2014-06-06 13:45:20 +05302488 if(!isEnabled() or !mModeOn) {
2489 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302490 return true;
2491 }
2492
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002493 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002494 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002495 sHandleTimeout = true;
2496 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002497
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002498 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002499 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002500
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002501 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2502 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002503 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002504 if(mCurrentFrame.isFBComposed[i]) continue;
2505
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002506 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002507 private_handle_t *hnd = (private_handle_t *)layer->handle;
2508 if(!hnd) {
2509 ALOGE("%s handle null", __FUNCTION__);
2510 return false;
2511 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002512
2513 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2514 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002515 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002516
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002517 int mdpIndex = mCurrentFrame.layerToMDP[i];
2518
Raj Kamal389d6e32014-08-04 14:43:24 +05302519 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302520 {
2521 MdpYUVPipeInfo& pipe_info =
2522 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2523 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2524 ovutils::eDest indexL = pipe_info.lIndex;
2525 ovutils::eDest indexR = pipe_info.rIndex;
2526 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302527 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302528 if(rot) {
2529 rot->queueBuffer(fd, offset);
2530 fd = rot->getDstMemId();
2531 offset = rot->getDstOffset();
2532 }
2533 if(indexL != ovutils::OV_INVALID) {
2534 ovutils::eDest destL = (ovutils::eDest)indexL;
2535 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2536 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2537 if (!ov.queueBuffer(fd, offset, destL)) {
2538 ALOGE("%s: queueBuffer failed for display:%d",
2539 __FUNCTION__, mDpy);
2540 return false;
2541 }
2542 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002543
radhakrishnac9a67412013-09-25 17:40:42 +05302544 if(indexR != ovutils::OV_INVALID) {
2545 ovutils::eDest destR = (ovutils::eDest)indexR;
2546 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2547 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2548 if (!ov.queueBuffer(fd, offset, destR)) {
2549 ALOGE("%s: queueBuffer failed for display:%d",
2550 __FUNCTION__, mDpy);
2551 return false;
2552 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002553 }
2554 }
radhakrishnac9a67412013-09-25 17:40:42 +05302555 else{
2556 MdpPipeInfoSplit& pipe_info =
2557 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2558 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002559
radhakrishnac9a67412013-09-25 17:40:42 +05302560 ovutils::eDest indexL = pipe_info.lIndex;
2561 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002562
radhakrishnac9a67412013-09-25 17:40:42 +05302563 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002564 uint32_t offset = (uint32_t)hnd->offset;
2565 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2566 if (!mDpy && (index != -1)) {
2567 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2568 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002569 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002570 }
radhakrishnac9a67412013-09-25 17:40:42 +05302571
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002572 if(ctx->mAD->draw(ctx, fd, offset)) {
2573 fd = ctx->mAD->getDstFd();
2574 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002575 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002576
radhakrishnac9a67412013-09-25 17:40:42 +05302577 if(rot) {
2578 rot->queueBuffer(fd, offset);
2579 fd = rot->getDstMemId();
2580 offset = rot->getDstOffset();
2581 }
2582
2583 //************* play left mixer **********
2584 if(indexL != ovutils::OV_INVALID) {
2585 ovutils::eDest destL = (ovutils::eDest)indexL;
2586 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2587 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2588 if (!ov.queueBuffer(fd, offset, destL)) {
2589 ALOGE("%s: queueBuffer failed for left mixer",
2590 __FUNCTION__);
2591 return false;
2592 }
2593 }
2594
2595 //************* play right mixer **********
2596 if(indexR != ovutils::OV_INVALID) {
2597 ovutils::eDest destR = (ovutils::eDest)indexR;
2598 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2599 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2600 if (!ov.queueBuffer(fd, offset, destR)) {
2601 ALOGE("%s: queueBuffer failed for right mixer",
2602 __FUNCTION__);
2603 return false;
2604 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002605 }
2606 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002607
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002608 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2609 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002610
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002611 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002612}
Saurabh Shahab47c692014-02-12 18:45:57 -08002613
2614//================MDPCompSrcSplit==============================================
2615bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002616 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002617 private_handle_t *hnd = (private_handle_t *)layer->handle;
2618 hwc_rect_t dst = layer->displayFrame;
2619 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2620 pipe_info.lIndex = ovutils::OV_INVALID;
2621 pipe_info.rIndex = ovutils::OV_INVALID;
2622
2623 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2624 //should have a higher priority than the right one. Pipe priorities are
2625 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002626
Saurabh Shahc62f3982014-03-05 14:28:26 -08002627 Overlay::PipeSpecs pipeSpecs;
2628 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2629 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2630 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2631 pipeSpecs.dpy = mDpy;
2632 pipeSpecs.fb = false;
2633
Saurabh Shahab47c692014-02-12 18:45:57 -08002634 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002635 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002636 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002637 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002638 }
2639
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002640 /* Use 2 pipes IF
2641 a) Layer's crop width is > 2048 or
2642 b) Layer's dest width > 2048 or
2643 c) On primary, driver has indicated with caps to split always. This is
2644 based on an empirically derived value of panel height. Applied only
2645 if the layer's width is > mixer's width
2646 */
2647
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302648 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002649 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302650 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002651 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2652 const uint32_t dstWidth = dst.right - dst.left;
2653 const uint32_t dstHeight = dst.bottom - dst.top;
2654 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002655 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002656 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2657 crop.bottom - crop.top;
2658 //Approximation to actual clock, ignoring the common factors in pipe and
2659 //mixer cases like line_time
2660 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2661 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002662
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002663 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2664 //pipe line length, we are still using 2 pipes. This is fine just because
2665 //this is source split where destination doesn't matter. Evaluate later to
2666 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002667 if(dstWidth > mdpHw.getMaxPipeWidth() or
2668 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002669 (primarySplitAlways and
2670 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002671 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002672 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002673 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002674 }
2675
2676 // Return values
2677 // 1 Left pipe is higher priority, do nothing.
2678 // 0 Pipes of same priority.
2679 //-1 Right pipe is of higher priority, needs swap.
2680 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2681 pipe_info.rIndex) == -1) {
2682 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002683 }
2684 }
2685
2686 return true;
2687}
2688
Saurabh Shahab47c692014-02-12 18:45:57 -08002689int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2690 PipeLayerPair& PipeLayerPair) {
2691 private_handle_t *hnd = (private_handle_t *)layer->handle;
2692 if(!hnd) {
2693 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2694 return -1;
2695 }
2696 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2697 MdpPipeInfoSplit& mdp_info =
2698 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2699 Rotator **rot = &PipeLayerPair.rot;
2700 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002701 eDest lDest = mdp_info.lIndex;
2702 eDest rDest = mdp_info.rIndex;
2703 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2704 hwc_rect_t dst = layer->displayFrame;
2705 int transform = layer->transform;
2706 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002707 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002708 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002709 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2710
2711 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2712 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2713
2714 // Handle R/B swap
2715 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2716 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2717 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2718 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2719 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2720 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002721 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002722 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2723 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002724 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002725 /* Calculate the external display position based on MDP downscale,
2726 ActionSafe, and extorientation features. */
2727 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002728
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002729 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302730 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002731 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002732
2733 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2734 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002735 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002736 }
2737
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002738 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002739 (*rot) = ctx->mRotMgr->getNext();
2740 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002741 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002742 //If the video is using a single pipe, enable BWC
2743 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002744 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2745 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002746 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002747 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002748 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002749 ALOGE("%s: configRotator failed!", __FUNCTION__);
2750 return -1;
2751 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002752 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002753 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002754 }
2755
2756 //If 2 pipes being used, divide layer into half, crop and dst
2757 hwc_rect_t cropL = crop;
2758 hwc_rect_t cropR = crop;
2759 hwc_rect_t dstL = dst;
2760 hwc_rect_t dstR = dst;
2761 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2762 cropL.right = (crop.right + crop.left) / 2;
2763 cropR.left = cropL.right;
2764 sanitizeSourceCrop(cropL, cropR, hnd);
2765
Saurabh Shahb729b192014-08-15 18:04:24 -07002766 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002767 //Swap crops on H flip since 2 pipes are being used
2768 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2769 hwc_rect_t tmp = cropL;
2770 cropL = cropR;
2771 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002772 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002773 }
2774
Saurabh Shahb729b192014-08-15 18:04:24 -07002775 //cropSwap trick: If the src and dst widths are both odd, let us say
2776 //2507, then splitting both into half would cause left width to be 1253
2777 //and right 1254. If crop is swapped because of H flip, this will cause
2778 //left crop width to be 1254, whereas left dst width remains 1253, thus
2779 //inducing a scaling that is unaccounted for. To overcome that we add 1
2780 //to the dst width if there is a cropSwap. So if the original width was
2781 //2507, the left dst width will be 1254. Even if the original width was
2782 //even for ex: 2508, the left dst width will still remain 1254.
2783 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002784 dstR.left = dstL.right;
2785 }
2786
2787 //For the mdp, since either we are pre-rotating or MDP does flips
2788 orient = OVERLAY_TRANSFORM_0;
2789 transform = 0;
2790
2791 //configure left pipe
2792 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002793 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002794 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2795 (ovutils::eBlending) getBlending(layer->blending));
2796
2797 if(configMdp(ctx->mOverlay, pargL, orient,
2798 cropL, dstL, metadata, lDest) < 0) {
2799 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2800 return -1;
2801 }
2802 }
2803
2804 //configure right pipe
2805 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002806 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002807 static_cast<eRotFlags>(rotFlags),
2808 layer->planeAlpha,
2809 (ovutils::eBlending) getBlending(layer->blending));
2810 if(configMdp(ctx->mOverlay, pargR, orient,
2811 cropR, dstR, metadata, rDest) < 0) {
2812 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2813 return -1;
2814 }
2815 }
2816
2817 return 0;
2818}
2819
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002820bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2821 Locker::Autolock _l(ctx->mDrawLock);
2822 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2823 char path[MAX_SYSFS_FILE_PATH];
2824 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2825 int fd = open(path, O_RDONLY);
2826 if(fd < 0) {
2827 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2828 return -1;
2829 }
2830 char value[4];
2831 ssize_t size_read = read(fd, value, sizeof(value)-1);
2832 if(size_read <= 0) {
2833 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2834 close(fd);
2835 return -1;
2836 }
2837 close(fd);
2838 value[size_read] = '\0';
2839 return atoi(value);
2840}
2841
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002842int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2843 Locker::Autolock _l(ctx->mDrawLock);
2844 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2845 char path[MAX_SYSFS_FILE_PATH];
2846 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2847 int fd = open(path, O_WRONLY);
2848 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002849 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002850 return -1;
2851 }
2852 char value[4];
2853 snprintf(value, sizeof(value), "%d", (int)enable);
2854 ssize_t ret = write(fd, value, strlen(value));
2855 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002856 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002857 close(fd);
2858 return -1;
2859 }
2860 close(fd);
2861 sIsPartialUpdateActive = enable;
2862 return 0;
2863}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002864
2865bool MDPComp::loadPerfLib() {
2866 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2867 bool success = false;
2868 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2869 ALOGE("vendor library not set in ro.vendor.extension_library");
2870 return false;
2871 }
2872
2873 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
2874 if(sLibPerfHint) {
2875 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
2876 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
2877 if (!sPerfLockAcquire || !sPerfLockRelease) {
2878 ALOGE("Failed to load symbols for perfLock");
2879 dlclose(sLibPerfHint);
2880 sLibPerfHint = NULL;
2881 return false;
2882 }
2883 success = true;
2884 ALOGI("Successfully Loaded perf hint API's");
2885 } else {
2886 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
2887 }
2888 return success;
2889}
2890
2891void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2892 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
2893 return;
2894 }
2895 static int count = sPerfHintWindow;
2896 static int perflockFlag = 0;
2897
2898 /* Send hint to mpctl when single layer is updated
2899 * for a successful number of windows. Hint release
2900 * happens immediately upon multiple layer update.
2901 */
2902 if (onlyVideosUpdating(ctx, list)) {
2903 if(count) {
2904 count--;
2905 }
2906 } else {
2907 if (perflockFlag) {
2908 perflockFlag = 0;
2909 sPerfLockRelease(sPerfLockHandle);
2910 }
2911 count = sPerfHintWindow;
2912 }
2913 if (count == 0 && !perflockFlag) {
2914 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
2915 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
2916 &perfHint, sizeof(perfHint)/sizeof(int));
2917 if(sPerfLockHandle < 0) {
2918 ALOGE("Perf Lock Acquire Failed");
2919 } else {
2920 perflockFlag = 1;
2921 }
2922 }
2923}
2924
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002925}; //namespace
2926