blob: b17bdafcf237c520ed26f74f4b1c9df5fc56bde9 [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))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530396 (not isValidDimension(ctx,layer)) ||
397 isSkipLayer(layer)) {
398 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700399 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
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700789 // if secondary is configuring or Padding round, fall back to video only
790 // composition and release all assigned non VIG pipes from primary.
791 if(isSecondaryConfiguring(ctx)) {
792 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
793 __FUNCTION__);
794 return false;
795 } else if(ctx->isPaddingRound) {
796 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
797 __FUNCTION__,mDpy);
798 return false;
799 }
800
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700801 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800802 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700803 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800804 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
805 return false;
806 }
807
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800808 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800809 hwc_layer_1_t* layer = &list->hwLayers[i];
810 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800811
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800812 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700813 if(!canUseRotator(ctx, mDpy)) {
814 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
815 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700816 return false;
817 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800818 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530819
820 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
821 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800822 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700823 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530824 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
825 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
826 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800827 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700828
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700829 if(ctx->mAD->isDoable()) {
830 return false;
831 }
832
Saurabh Shahaa236822013-04-24 18:07:26 -0700833 //If all above hard conditions are met we can do full or partial MDP comp.
834 bool ret = false;
835 if(fullMDPComp(ctx, list)) {
836 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700837 } else if(fullMDPCompWithPTOR(ctx, list)) {
838 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700839 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700840 ret = true;
841 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530842
Saurabh Shahaa236822013-04-24 18:07:26 -0700843 return ret;
844}
845
846bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700847
848 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
849 return false;
850
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700851 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
852 for(int i = 0; i < numAppLayers; i++) {
853 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700854 if(not mCurrentFrame.drop[i] and
855 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700856 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
857 return false;
858 }
859 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800860
Saurabh Shahaa236822013-04-24 18:07:26 -0700861 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700862 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
863 sizeof(mCurrentFrame.isFBComposed));
864 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
865 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700866
Raj Kamal389d6e32014-08-04 14:43:24 +0530867 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800868 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530869 }
870
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800871 if(!postHeuristicsHandling(ctx, list)) {
872 ALOGD_IF(isDebug(), "post heuristic handling failed");
873 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700874 return false;
875 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700876 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
877 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700878 return true;
879}
880
Sushil Chauhandefd3522014-05-13 18:17:12 -0700881/* Full MDP Composition with Peripheral Tiny Overlap Removal.
882 * MDP bandwidth limitations can be avoided, if the overlap region
883 * covered by the smallest layer at a higher z-order, gets composed
884 * by Copybit on a render buffer, which can be queued to MDP.
885 */
886bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
887 hwc_display_contents_1_t* list) {
888
889 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
890 const int stagesForMDP = min(sMaxPipesPerMixer,
891 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
892
893 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700894 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700895 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
896 return false;
897 }
898
899 // Frame level checks
900 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
901 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
902 isSecurePresent(ctx, mDpy)) {
903 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
904 return false;
905 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700906 // MDP comp checks
907 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700908 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700909 if(not isSupportedForMDPComp(ctx, layer)) {
910 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
911 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700912 }
913 }
914
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 /* We cannot use this composition mode, if:
916 1. A below layer needs scaling.
917 2. Overlap is not peripheral to display.
918 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700919 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700920 */
921
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700922 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
923 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
924 memset(overlapRect, 0, sizeof(overlapRect));
925 int layerPixelCount, minPixelCount = 0;
926 int numPTORLayersFound = 0;
927 for (int i = numAppLayers-1; (i >= 0 &&
928 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700929 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700930 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700931 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700932 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
933 // PTOR layer should be peripheral and cannot have transform
934 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
935 has90Transform(layer)) {
936 continue;
937 }
938 if((3 * (layerPixelCount + minPixelCount)) >
939 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
940 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
941 continue;
942 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700943 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 for (int j = i-1; j >= 0; j--) {
945 // Check if the layers below this layer qualifies for PTOR comp
946 hwc_layer_1_t* layer = &list->hwLayers[j];
947 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700948 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700949 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700950 if (isValidRect(getIntersection(dispFrame, disFrame))) {
951 if (has90Transform(layer) || needsScaling(layer)) {
952 found = false;
953 break;
954 }
955 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 }
957 }
958 // Store the minLayer Index
959 if(found) {
960 minLayerIndex[numPTORLayersFound] = i;
961 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
962 minPixelCount += layerPixelCount;
963 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700964 }
965 }
966
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700967 // No overlap layers
968 if (!numPTORLayersFound)
969 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700970
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700971 // Store the displayFrame and the sourceCrops of the layers
972 hwc_rect_t displayFrame[numAppLayers];
973 hwc_rect_t sourceCrop[numAppLayers];
974 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700975 hwc_layer_1_t* layer = &list->hwLayers[i];
976 displayFrame[i] = layer->displayFrame;
977 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700978 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700979
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530980 /**
981 * It's possible that 2 PTOR layers might have overlapping.
982 * In such case, remove the intersection(again if peripheral)
983 * from the lower PTOR layer to avoid overlapping.
984 * If intersection is not on peripheral then compromise
985 * by reducing number of PTOR layers.
986 **/
987 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
988 if(isValidRect(commonRect)) {
989 overlapRect[1] = deductRect(overlapRect[1], commonRect);
990 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
991 }
992
993 ctx->mPtorInfo.count = numPTORLayersFound;
994 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
995 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
996 }
997
998 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
999 // reset PTOR
1000 ctx->mPtorInfo.count = 0;
1001 if(isValidRect(commonRect)) {
1002 // If PTORs are intersecting restore displayframe of PTOR[1]
1003 // before returning, as we have modified it above.
1004 list->hwLayers[minLayerIndex[1]].displayFrame =
1005 displayFrame[minLayerIndex[1]];
1006 }
1007 return false;
1008 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001009 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1010 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1011
Xu Yangcda012c2014-07-30 21:57:21 +08001012 // Store the blending mode, planeAlpha, and transform of PTOR layers
1013 int32_t blending[numPTORLayersFound];
1014 uint8_t planeAlpha[numPTORLayersFound];
1015 uint32_t transform[numPTORLayersFound];
1016
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001017 for(int j = 0; j < numPTORLayersFound; j++) {
1018 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001019
1020 // Update src crop of PTOR layer
1021 hwc_layer_1_t* layer = &list->hwLayers[index];
1022 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1023 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1024 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1025 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1026
1027 // Store & update w, h, format of PTOR layer
1028 private_handle_t *hnd = (private_handle_t *)layer->handle;
1029 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1030 layerWhf[j] = whf;
1031 hnd->width = renderBuf->width;
1032 hnd->height = renderBuf->height;
1033 hnd->format = renderBuf->format;
1034
Xu Yangcda012c2014-07-30 21:57:21 +08001035 // Store & update blending mode, planeAlpha and transform of PTOR layer
1036 blending[j] = layer->blending;
1037 planeAlpha[j] = layer->planeAlpha;
1038 transform[j] = layer->transform;
1039 layer->blending = HWC_BLENDING_NONE;
1040 layer->planeAlpha = 0xFF;
1041 layer->transform = 0;
1042
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001043 // Remove overlap from crop & displayFrame of below layers
1044 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001045 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001046 if(!isValidRect(getIntersection(layer->displayFrame,
1047 overlapRect[j]))) {
1048 continue;
1049 }
1050 // Update layer attributes
1051 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1052 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301053 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001054 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1055 layer->transform);
1056 layer->sourceCropf.left = (float)srcCrop.left;
1057 layer->sourceCropf.top = (float)srcCrop.top;
1058 layer->sourceCropf.right = (float)srcCrop.right;
1059 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1060 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001061 }
1062
1063 mCurrentFrame.mdpCount = numAppLayers;
1064 mCurrentFrame.fbCount = 0;
1065 mCurrentFrame.fbZ = -1;
1066
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301067 for (int j = 0; j < numAppLayers; j++) {
1068 if(isValidRect(list->hwLayers[j].displayFrame)) {
1069 mCurrentFrame.isFBComposed[j] = false;
1070 } else {
1071 mCurrentFrame.mdpCount--;
1072 mCurrentFrame.drop[j] = true;
1073 }
1074 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001075
1076 bool result = postHeuristicsHandling(ctx, list);
1077
1078 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001079 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001080 hwc_layer_1_t* layer = &list->hwLayers[i];
1081 layer->displayFrame = displayFrame[i];
1082 layer->sourceCropf.left = (float)sourceCrop[i].left;
1083 layer->sourceCropf.top = (float)sourceCrop[i].top;
1084 layer->sourceCropf.right = (float)sourceCrop[i].right;
1085 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1086 }
1087
Xu Yangcda012c2014-07-30 21:57:21 +08001088 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001089 for (int i = 0; i < numPTORLayersFound; i++) {
1090 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001091 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001092 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1093 hnd->width = layerWhf[i].w;
1094 hnd->height = layerWhf[i].h;
1095 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001096 layer->blending = blending[i];
1097 layer->planeAlpha = planeAlpha[i];
1098 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001099 }
1100
Sushil Chauhandefd3522014-05-13 18:17:12 -07001101 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001102 // reset PTOR
1103 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001104 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001105 } else {
1106 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1107 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001108 }
1109
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001110 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1111 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001112 return result;
1113}
1114
Saurabh Shahaa236822013-04-24 18:07:26 -07001115bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1116{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001117 if(!sEnableMixedMode) {
1118 //Mixed mode is disabled. No need to even try caching.
1119 return false;
1120 }
1121
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001122 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301123 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1124 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001125 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001126 cacheBasedComp(ctx, list);
1127 } else {
1128 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001129 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001130 }
1131
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001132 return ret;
1133}
1134
1135bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1136 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001137 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1138 return false;
1139
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001140 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001141 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001142 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001143
1144 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1145 for(int i = 0; i < numAppLayers; i++) {
1146 if(!mCurrentFrame.isFBComposed[i]) {
1147 hwc_layer_1_t* layer = &list->hwLayers[i];
1148 if(not isSupportedForMDPComp(ctx, layer)) {
1149 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1150 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001151 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001152 return false;
1153 }
1154 }
1155 }
1156
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001157 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001158 /* mark secure RGB layers for MDP comp */
1159 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301160 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001161 if(!ret) {
1162 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001163 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001164 return false;
1165 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001166
1167 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001168
Raj Kamal389d6e32014-08-04 14:43:24 +05301169 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001170 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301171 }
1172
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001173 if(!postHeuristicsHandling(ctx, list)) {
1174 ALOGD_IF(isDebug(), "post heuristic handling failed");
1175 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001176 return false;
1177 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001178 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1179 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001180
Saurabh Shahaa236822013-04-24 18:07:26 -07001181 return true;
1182}
1183
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001184bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001185 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001186 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1187 return false;
1188
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001189 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001190 return false;
1191 }
1192
Saurabh Shahb772ae32013-11-18 15:40:02 -08001193 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001194 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1195 const int stagesForMDP = min(sMaxPipesPerMixer,
1196 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001197
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001198 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1199 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1200 int lastMDPSupportedIndex = numAppLayers;
1201 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001202
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001203 //Find the minimum MDP batch size
1204 for(int i = 0; i < numAppLayers;i++) {
1205 if(mCurrentFrame.drop[i]) {
1206 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001207 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001208 }
1209 hwc_layer_1_t* layer = &list->hwLayers[i];
1210 if(not isSupportedForMDPComp(ctx, layer)) {
1211 lastMDPSupportedIndex = i;
1212 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1213 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001214 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001215 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001216 }
1217
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001218 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1219 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1220 mCurrentFrame.dropCount);
1221
1222 //Start at a point where the fb batch should at least have 2 layers, for
1223 //this mode to be justified.
1224 while(fbBatchSize < 2) {
1225 ++fbBatchSize;
1226 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001227 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001228
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001229 //If there are no layers for MDP, this mode doesnt make sense.
1230 if(mdpBatchSize < 1) {
1231 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1232 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001233 return false;
1234 }
1235
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001236 mCurrentFrame.reset(numAppLayers);
1237
1238 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1239 while(mdpBatchSize > 0) {
1240 //Mark layers for MDP comp
1241 int mdpBatchLeft = mdpBatchSize;
1242 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1243 if(mCurrentFrame.drop[i]) {
1244 continue;
1245 }
1246 mCurrentFrame.isFBComposed[i] = false;
1247 --mdpBatchLeft;
1248 }
1249
1250 mCurrentFrame.fbZ = mdpBatchSize;
1251 mCurrentFrame.fbCount = fbBatchSize;
1252 mCurrentFrame.mdpCount = mdpBatchSize;
1253
1254 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1255 __FUNCTION__, mdpBatchSize, fbBatchSize,
1256 mCurrentFrame.dropCount);
1257
1258 if(postHeuristicsHandling(ctx, list)) {
1259 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001260 __FUNCTION__);
1261 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1262 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001263 return true;
1264 }
1265
1266 reset(ctx);
1267 --mdpBatchSize;
1268 ++fbBatchSize;
1269 }
1270
1271 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001272}
1273
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001274bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301275 if(mDpy or isSecurePresent(ctx, mDpy) or
1276 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001277 return false;
1278 }
1279 return true;
1280}
1281
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001282bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1283 hwc_display_contents_1_t* list){
1284 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1285 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001286 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001287 return false;
1288 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001289 if(ctx->listStats[mDpy].secureUI)
1290 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001291 return true;
1292}
1293
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001294bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1295 hwc_display_contents_1_t* list) {
1296 const bool secureOnly = true;
1297 return videoOnlyComp(ctx, list, not secureOnly) or
1298 videoOnlyComp(ctx, list, secureOnly);
1299}
1300
1301bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001302 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001303 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1304 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301305
Saurabh Shahaa236822013-04-24 18:07:26 -07001306 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301307 if(!isSecurePresent(ctx, mDpy)) {
1308 /* Bail out if we are processing only secured video layers
1309 * and we dont have any */
1310 if(secureOnly) {
1311 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1312 return false;
1313 }
1314 /* No Idle fall back for secure video layers and if there is only
1315 * single layer being composed. */
1316 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1317 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1318 return false;
1319 }
1320 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001321
Saurabh Shahaa236822013-04-24 18:07:26 -07001322 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001323 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001324 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001325 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001326
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001327 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1328 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001329 return false;
1330 }
1331
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001332 if(mCurrentFrame.fbCount)
1333 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001334
Raj Kamal389d6e32014-08-04 14:43:24 +05301335 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001336 adjustForSourceSplit(ctx, list);
1337 }
1338
1339 if(!postHeuristicsHandling(ctx, list)) {
1340 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301341 if(errno == ENOBUFS) {
1342 ALOGD_IF(isDebug(), "SMP Allocation failed");
1343 //On SMP allocation failure in video only comp add padding round
1344 ctx->isPaddingRound = true;
1345 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001346 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001347 return false;
1348 }
1349
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001350 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1351 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001352 return true;
1353}
1354
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001355/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1356bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1357 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001358 // Fall back to video only composition, if AIV video mode is enabled
1359 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001360 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1361 __FUNCTION__, mDpy);
1362 return false;
1363 }
1364
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001365 const bool secureOnly = true;
1366 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1367 mdpOnlyLayersComp(ctx, list, secureOnly);
1368
1369}
1370
1371bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1372 hwc_display_contents_1_t* list, bool secureOnly) {
1373
1374 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1375 return false;
1376
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301377 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1378 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1379 /* Bail out if we are processing only secured video/ui layers
1380 * and we dont have any */
1381 if(secureOnly) {
1382 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1383 return false;
1384 }
1385 /* No Idle fall back for secure video/ui layers and if there is only
1386 * single layer being composed. */
1387 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1388 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1389 return false;
1390 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001391 }
1392
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001393 /* Bail out if we dont have any secure RGB layers */
1394 if (!ctx->listStats[mDpy].secureRGBCount) {
1395 reset(ctx);
1396 return false;
1397 }
1398
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001399 mCurrentFrame.reset(numAppLayers);
1400 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1401
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001402 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001403 /* mark secure RGB layers for MDP comp */
1404 updateSecureRGB(ctx, list);
1405
1406 if(mCurrentFrame.mdpCount == 0) {
1407 reset(ctx);
1408 return false;
1409 }
1410
1411 /* find the maximum batch of layers to be marked for framebuffer */
1412 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1413 if(!ret) {
1414 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1415 reset(ctx);
1416 return false;
1417 }
1418
1419 if(sEnableYUVsplit){
1420 adjustForSourceSplit(ctx, list);
1421 }
1422
1423 if(!postHeuristicsHandling(ctx, list)) {
1424 ALOGD_IF(isDebug(), "post heuristic handling failed");
1425 reset(ctx);
1426 return false;
1427 }
1428
1429 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1430 __FUNCTION__);
1431 return true;
1432}
1433
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001434/* Checks for conditions where YUV layers cannot be bypassed */
1435bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001436 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001437 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001438 return false;
1439 }
1440
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001441 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001442 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1443 return false;
1444 }
1445
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001446 if(isSecuring(ctx, layer)) {
1447 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1448 return false;
1449 }
1450
Saurabh Shah4fdde762013-04-30 18:47:33 -07001451 if(!isValidDimension(ctx, layer)) {
1452 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1453 __FUNCTION__);
1454 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001455 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001456
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001457 if(layer->planeAlpha < 0xFF) {
1458 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1459 in video only mode",
1460 __FUNCTION__);
1461 return false;
1462 }
1463
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001464 return true;
1465}
1466
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001467/* Checks for conditions where Secure RGB layers cannot be bypassed */
1468bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1469 if(isSkipLayer(layer)) {
1470 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1471 __FUNCTION__, mDpy);
1472 return false;
1473 }
1474
1475 if(isSecuring(ctx, layer)) {
1476 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1477 return false;
1478 }
1479
1480 if(not isSupportedForMDPComp(ctx, layer)) {
1481 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1482 __FUNCTION__);
1483 return false;
1484 }
1485 return true;
1486}
1487
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301488/* starts at fromIndex and check for each layer to find
1489 * if it it has overlapping with any Updating layer above it in zorder
1490 * till the end of the batch. returns true if it finds any intersection */
1491bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1492 int fromIndex, int toIndex) {
1493 for(int i = fromIndex; i < toIndex; i++) {
1494 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1495 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1496 return false;
1497 }
1498 }
1499 }
1500 return true;
1501}
1502
1503/* Checks if given layer at targetLayerIndex has any
1504 * intersection with all the updating layers in beween
1505 * fromIndex and toIndex. Returns true if it finds intersectiion */
1506bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1507 int fromIndex, int toIndex, int targetLayerIndex) {
1508 for(int i = fromIndex; i <= toIndex; i++) {
1509 if(!mCurrentFrame.isFBComposed[i]) {
1510 if(areLayersIntersecting(&list->hwLayers[i],
1511 &list->hwLayers[targetLayerIndex])) {
1512 return true;
1513 }
1514 }
1515 }
1516 return false;
1517}
1518
1519int MDPComp::getBatch(hwc_display_contents_1_t* list,
1520 int& maxBatchStart, int& maxBatchEnd,
1521 int& maxBatchCount) {
1522 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301523 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001524 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301525 while (i < mCurrentFrame.layerCount) {
1526 int batchCount = 0;
1527 int batchStart = i;
1528 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001529 /* Adjust batch Z order with the dropped layers so far */
1530 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301531 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301532 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301533 while(i < mCurrentFrame.layerCount) {
1534 if(!mCurrentFrame.isFBComposed[i]) {
1535 if(!batchCount) {
1536 i++;
1537 break;
1538 }
1539 updatingLayersAbove++;
1540 i++;
1541 continue;
1542 } else {
1543 if(mCurrentFrame.drop[i]) {
1544 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001545 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301546 continue;
1547 } else if(updatingLayersAbove <= 0) {
1548 batchCount++;
1549 batchEnd = i;
1550 i++;
1551 continue;
1552 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1553
1554 // We have a valid updating layer already. If layer-i not
1555 // have overlapping with all updating layers in between
1556 // batch-start and i, then we can add layer i to batch.
1557 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1558 batchCount++;
1559 batchEnd = i;
1560 i++;
1561 continue;
1562 } else if(canPushBatchToTop(list, batchStart, i)) {
1563 //If All the non-updating layers with in this batch
1564 //does not have intersection with the updating layers
1565 //above in z-order, then we can safely move the batch to
1566 //higher z-order. Increment fbZ as it is moving up.
1567 if( firstZReverseIndex < 0) {
1568 firstZReverseIndex = i;
1569 }
1570 batchCount++;
1571 batchEnd = i;
1572 fbZ += updatingLayersAbove;
1573 i++;
1574 updatingLayersAbove = 0;
1575 continue;
1576 } else {
1577 //both failed.start the loop again from here.
1578 if(firstZReverseIndex >= 0) {
1579 i = firstZReverseIndex;
1580 }
1581 break;
1582 }
1583 }
1584 }
1585 }
1586 if(batchCount > maxBatchCount) {
1587 maxBatchCount = batchCount;
1588 maxBatchStart = batchStart;
1589 maxBatchEnd = batchEnd;
1590 fbZOrder = fbZ;
1591 }
1592 }
1593 return fbZOrder;
1594}
1595
1596bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1597 hwc_display_contents_1_t* list) {
1598 /* Idea is to keep as many non-updating(cached) layers in FB and
1599 * send rest of them through MDP. This is done in 2 steps.
1600 * 1. Find the maximum contiguous batch of non-updating layers.
1601 * 2. See if we can improve this batch size for caching by adding
1602 * opaque layers around the batch, if they don't have
1603 * any overlapping with the updating layers in between.
1604 * NEVER mark an updating layer for caching.
1605 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001606
1607 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001608 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001609 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301610 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001611
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001612 /* Nothing is cached. No batching needed */
1613 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001614 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001615 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001616
1617 /* No MDP comp layers, try to use other comp modes */
1618 if(mCurrentFrame.mdpCount == 0) {
1619 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001620 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301622 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001623
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301624 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001625 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001626 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001627 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301628 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001629 if(!mCurrentFrame.drop[i]){
1630 //If an unsupported layer is being attempted to
1631 //be pulled out we should fail
1632 if(not isSupportedForMDPComp(ctx, layer)) {
1633 return false;
1634 }
1635 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001636 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001637 }
1638 }
1639
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301640 // update the frame data
1641 mCurrentFrame.fbZ = fbZ;
1642 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001643 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001644 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001645
1646 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301647 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001648
1649 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001650}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001651
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001652void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001653 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001654 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001655 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001657 for(int i = 0; i < numAppLayers; i++) {
1658 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001659 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001660 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001661 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001663 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664 }
1665 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001666
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001667 frame.fbCount = fbCount;
1668 frame.mdpCount = frame.layerCount - frame.fbCount
1669 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001670
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001671 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1672 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001673}
1674
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001675// drop other non-AIV layers from external display list.
1676void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001677 hwc_display_contents_1_t* list) {
1678 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1679 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001680 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001681 mCurrentFrame.dropCount++;
1682 mCurrentFrame.drop[i] = true;
1683 }
1684 }
1685 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1686 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1687 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1688 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1689 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1690 mCurrentFrame.dropCount);
1691}
1692
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001693void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001694 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001695 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1696 for(int index = 0;index < nYuvCount; index++){
1697 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1698 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1699
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001700 if(mCurrentFrame.drop[nYuvIndex]) {
1701 continue;
1702 }
1703
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001704 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001705 if(!frame.isFBComposed[nYuvIndex]) {
1706 frame.isFBComposed[nYuvIndex] = true;
1707 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708 }
1709 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001710 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001711 private_handle_t *hnd = (private_handle_t *)layer->handle;
1712 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001713 frame.isFBComposed[nYuvIndex] = false;
1714 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001715 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001716 }
1717 }
1718 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001719
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001720 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1721 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001722}
1723
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001724void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1725 hwc_display_contents_1_t* list) {
1726 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1727 for(int index = 0;index < nSecureRGBCount; index++){
1728 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1729 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1730
1731 if(!isSecureRGBDoable(ctx, layer)) {
1732 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1733 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1734 mCurrentFrame.fbCount++;
1735 }
1736 } else {
1737 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1738 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1739 mCurrentFrame.fbCount--;
1740 }
1741 }
1742 }
1743
1744 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1745 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1746 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1747 mCurrentFrame.fbCount);
1748}
1749
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001750hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1751 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001752 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001753
1754 /* Update only the region of FB needed for composition */
1755 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1756 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1757 hwc_layer_1_t* layer = &list->hwLayers[i];
1758 hwc_rect_t dst = layer->displayFrame;
1759 fbRect = getUnion(fbRect, dst);
1760 }
1761 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001762 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001763 return fbRect;
1764}
1765
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001766bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1767 hwc_display_contents_1_t* list) {
1768
1769 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001770 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001771 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1772 return false;
1773 }
1774
1775 //Limitations checks
1776 if(!hwLimitationsCheck(ctx, list)) {
1777 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1778 return false;
1779 }
1780
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001781 //Configure framebuffer first if applicable
1782 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001783 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001784 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1785 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001786 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1787 __FUNCTION__);
1788 return false;
1789 }
1790 }
1791
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001792 mCurrentFrame.map();
1793
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001794 if(!allocLayerPipes(ctx, list)) {
1795 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001796 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001797 }
1798
1799 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001800 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001801 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001802 int mdpIndex = mCurrentFrame.layerToMDP[index];
1803 hwc_layer_1_t* layer = &list->hwLayers[index];
1804
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301805 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1806 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1807 mdpNextZOrder++;
1808 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001809 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1810 cur_pipe->zOrder = mdpNextZOrder++;
1811
radhakrishnac9a67412013-09-25 17:40:42 +05301812 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301813 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301814 if(configure4k2kYuv(ctx, layer,
1815 mCurrentFrame.mdpToLayer[mdpIndex])
1816 != 0 ){
1817 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1818 for layer %d",__FUNCTION__, index);
1819 return false;
1820 }
1821 else{
1822 mdpNextZOrder++;
1823 }
1824 continue;
1825 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001826 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1827 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301828 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001829 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001830 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001831 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001832 }
1833
Saurabh Shaha36be922013-12-16 18:18:39 -08001834 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1835 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1836 ,__FUNCTION__, mDpy);
1837 return false;
1838 }
1839
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001840 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001841 return true;
1842}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001843
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001844bool MDPComp::resourceCheck(hwc_context_t* ctx,
1845 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001846 const bool fbUsed = mCurrentFrame.fbCount;
1847 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1848 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1849 return false;
1850 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001851
1852 //Will benefit cases where a video has non-updating background.
1853 if((mDpy > HWC_DISPLAY_PRIMARY) and
1854 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1855 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1856 return false;
1857 }
1858
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001859 // Init rotCount to number of rotate sessions used by other displays
1860 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1861 // Count the number of rotator sessions required for current display
1862 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1863 if(!mCurrentFrame.isFBComposed[index]) {
1864 hwc_layer_1_t* layer = &list->hwLayers[index];
1865 private_handle_t *hnd = (private_handle_t *)layer->handle;
1866 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1867 rotCount++;
1868 }
1869 }
1870 }
1871 // if number of layers to rotate exceeds max rotator sessions, bail out.
1872 if(rotCount > RotMgr::MAX_ROT_SESS) {
1873 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1874 __FUNCTION__, mDpy);
1875 return false;
1876 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001877 return true;
1878}
1879
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301880bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1881 hwc_display_contents_1_t* list) {
1882
1883 //A-family hw limitation:
1884 //If a layer need alpha scaling, MDP can not support.
1885 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1886 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1887 if(!mCurrentFrame.isFBComposed[i] &&
1888 isAlphaScaled( &list->hwLayers[i])) {
1889 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1890 return false;
1891 }
1892 }
1893 }
1894
1895 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1896 //If multiple layers requires downscaling and also they are overlapping
1897 //fall back to GPU since MDSS can not handle it.
1898 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1899 qdutils::MDPVersion::getInstance().is8x26()) {
1900 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1901 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1902 if(!mCurrentFrame.isFBComposed[i] &&
1903 isDownscaleRequired(botLayer)) {
1904 //if layer-i is marked for MDP and needs downscaling
1905 //check if any MDP layer on top of i & overlaps with layer-i
1906 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1907 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1908 if(!mCurrentFrame.isFBComposed[j] &&
1909 isDownscaleRequired(topLayer)) {
1910 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1911 topLayer->displayFrame);
1912 if(isValidRect(r))
1913 return false;
1914 }
1915 }
1916 }
1917 }
1918 }
1919 return true;
1920}
1921
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001922// Checks only if videos or single layer(RGB) is updating
1923// which is used for setting dynamic fps or perf hint for single
1924// layer video playback
1925bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1926 hwc_display_contents_1_t* list) {
1927 bool support = false;
1928 FrameInfo frame;
1929 frame.reset(mCurrentFrame.layerCount);
1930 memset(&frame.drop, 0, sizeof(frame.drop));
1931 frame.dropCount = 0;
1932 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1933 updateLayerCache(ctx, list, frame);
1934 updateYUV(ctx, list, false /*secure only*/, frame);
1935 // There are only updating YUV layers or there is single RGB
1936 // Layer(Youtube)
1937 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1938 (frame.layerCount == 1)) {
1939 support = true;
1940 }
1941 return support;
1942}
1943
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301944void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1945 //For primary display, set the dynamic refreshrate
1946 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1947 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301948 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1949 MDPVersion& mdpHw = MDPVersion::getInstance();
1950 if(sIdleFallBack) {
1951 //Set minimum panel refresh rate during idle timeout
1952 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001953 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301954 //Set the new fresh rate, if there is only one updating YUV layer
1955 //or there is one single RGB layer with this request
1956 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1957 }
1958 setRefreshRate(ctx, mDpy, refreshRate);
1959 }
1960}
1961
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001962int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001963 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001964 char property[PROPERTY_VALUE_MAX];
1965
Raj Kamal4393eaa2014-06-06 13:45:20 +05301966 if(!ctx || !list) {
1967 ALOGE("%s: Invalid context or list",__FUNCTION__);
1968 mCachedFrame.reset();
1969 return -1;
1970 }
1971
1972 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001973 if(mDpy == HWC_DISPLAY_PRIMARY) {
1974 sSimulationFlags = 0;
1975 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1976 int currentFlags = atoi(property);
1977 if(currentFlags != sSimulationFlags) {
1978 sSimulationFlags = currentFlags;
1979 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1980 sSimulationFlags, sSimulationFlags);
1981 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001982 }
1983 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001984 // reset PTOR
1985 if(!mDpy)
1986 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001987
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301988 //reset old data
1989 mCurrentFrame.reset(numLayers);
1990 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1991 mCurrentFrame.dropCount = 0;
1992
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301993 //Do not cache the information for next draw cycle.
1994 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1995 ALOGI("%s: Unsupported layer count for mdp composition",
1996 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001997 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301998#ifdef DYNAMIC_FPS
1999 setDynRefreshRate(ctx, list);
2000#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002001 return -1;
2002 }
2003
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002004 // Detect the start of animation and fall back to GPU only once to cache
2005 // all the layers in FB and display FB content untill animation completes.
2006 if(ctx->listStats[mDpy].isDisplayAnimating) {
2007 mCurrentFrame.needsRedraw = false;
2008 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2009 mCurrentFrame.needsRedraw = true;
2010 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2011 }
2012 setMDPCompLayerFlags(ctx, list);
2013 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302014#ifdef DYNAMIC_FPS
2015 setDynRefreshRate(ctx, list);
2016#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002017 ret = -1;
2018 return ret;
2019 } else {
2020 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2021 }
2022
Saurabh Shahb39f8152013-08-22 10:21:44 -07002023 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002024 if(isFrameDoable(ctx)) {
2025 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002026 // if AIV Video mode is enabled, drop all non AIV layers from the
2027 // external display list.
2028 if(ctx->listStats[mDpy].mAIVVideoMode) {
2029 dropNonAIVLayers(ctx, list);
2030 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002031
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002032 // if tryFullFrame fails, try to push all video and secure RGB layers
2033 // to MDP for composition.
2034 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002035 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302036 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002037 setMDPCompLayerFlags(ctx, list);
2038 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002039 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002040 reset(ctx);
2041 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2042 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002043 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002044 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2045 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002046 }
2047 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302048 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2049 enablePartialUpdateForMDP3) {
2050 generateROI(ctx, list);
2051 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2052 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2053 }
2054 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002055 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2056 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002057 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002058 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002059
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002060 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002061 ALOGD("GEOMETRY change: %d",
2062 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002063 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002064 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002065 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002066 }
2067
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002068#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302069 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002070#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002071 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002072
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002073 mCachedFrame.cacheAll(list);
2074 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002075 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002076}
2077
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002078bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302079
2080 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302081 int mdpIndex = mCurrentFrame.layerToMDP[index];
2082 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2083 info.pipeInfo = new MdpYUVPipeInfo;
2084 info.rot = NULL;
2085 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302086
2087 pipe_info.lIndex = ovutils::OV_INVALID;
2088 pipe_info.rIndex = ovutils::OV_INVALID;
2089
Saurabh Shahc62f3982014-03-05 14:28:26 -08002090 Overlay::PipeSpecs pipeSpecs;
2091 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2092 pipeSpecs.needsScaling = true;
2093 pipeSpecs.dpy = mDpy;
2094 pipeSpecs.fb = false;
2095
2096 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302097 if(pipe_info.lIndex == ovutils::OV_INVALID){
2098 bRet = false;
2099 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2100 __FUNCTION__);
2101 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002102 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302103 if(pipe_info.rIndex == ovutils::OV_INVALID){
2104 bRet = false;
2105 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2106 __FUNCTION__);
2107 }
2108 return bRet;
2109}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002110
2111int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2112 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002113 if (ctx->mPtorInfo.isActive()) {
2114 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002115 if (fd < 0) {
2116 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002117 }
2118 }
2119 return fd;
2120}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002121//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002122
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002123void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302124 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002125 //If 4k2k Yuv layer split is possible, and if
2126 //fbz is above 4k2k layer, increment fb zorder by 1
2127 //as we split 4k2k layer and increment zorder for right half
2128 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002129 if(!ctx)
2130 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002131 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302132 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2133 index++) {
2134 if(!mCurrentFrame.isFBComposed[index]) {
2135 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2136 mdpNextZOrder++;
2137 }
2138 mdpNextZOrder++;
2139 hwc_layer_1_t* layer = &list->hwLayers[index];
2140 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302141 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302142 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2143 mCurrentFrame.fbZ += 1;
2144 mdpNextZOrder++;
2145 //As we split 4kx2k yuv layer and program to 2 VG pipes
2146 //(if available) increase mdpcount by 1.
2147 mCurrentFrame.mdpCount++;
2148 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002149 }
2150 }
2151 }
radhakrishnac9a67412013-09-25 17:40:42 +05302152}
2153
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002154/*
2155 * Configures pipe(s) for MDP composition
2156 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002157int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002158 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002159 MdpPipeInfoNonSplit& mdp_info =
2160 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302161 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002162 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002163 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002164
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002165 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2166 __FUNCTION__, layer, zOrder, dest);
2167
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002168 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002169 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002170}
2171
Saurabh Shah88e4d272013-09-03 13:31:29 -07002172bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002173 hwc_display_contents_1_t* list) {
2174 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002175
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002176 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002177
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002178 hwc_layer_1_t* layer = &list->hwLayers[index];
2179 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302180 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002181 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302182 continue;
2183 }
2184 }
2185
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002186 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002187 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002188 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002189 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002190 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002191
Saurabh Shahc62f3982014-03-05 14:28:26 -08002192 Overlay::PipeSpecs pipeSpecs;
2193 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2194 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2195 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2196 (qdutils::MDPVersion::getInstance().is8x26() and
2197 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2198 pipeSpecs.dpy = mDpy;
2199 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002200 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002201
Saurabh Shahc62f3982014-03-05 14:28:26 -08002202 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2203
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002204 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002205 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002206 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002207 }
2208 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002209 return true;
2210}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002211
radhakrishnac9a67412013-09-25 17:40:42 +05302212int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2213 PipeLayerPair& PipeLayerPair) {
2214 MdpYUVPipeInfo& mdp_info =
2215 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2216 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302217 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302218 eDest lDest = mdp_info.lIndex;
2219 eDest rDest = mdp_info.rIndex;
2220
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002221 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302222 lDest, rDest, &PipeLayerPair.rot);
2223}
2224
Saurabh Shah88e4d272013-09-03 13:31:29 -07002225bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002226
Raj Kamal4393eaa2014-06-06 13:45:20 +05302227 if(!isEnabled() or !mModeOn) {
2228 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302229 return true;
2230 }
2231
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002232 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002233 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002234 sHandleTimeout = true;
2235 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002236
2237 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002238 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002239
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002240 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2241 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002242 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002243 if(mCurrentFrame.isFBComposed[i]) continue;
2244
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002245 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002246 private_handle_t *hnd = (private_handle_t *)layer->handle;
2247 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002248 if (!(layer->flags & HWC_COLOR_FILL)) {
2249 ALOGE("%s handle null", __FUNCTION__);
2250 return false;
2251 }
2252 // No PLAY for Color layer
2253 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2254 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002255 }
2256
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002257 int mdpIndex = mCurrentFrame.layerToMDP[i];
2258
Raj Kamal389d6e32014-08-04 14:43:24 +05302259 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302260 {
2261 MdpYUVPipeInfo& pipe_info =
2262 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2263 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2264 ovutils::eDest indexL = pipe_info.lIndex;
2265 ovutils::eDest indexR = pipe_info.rIndex;
2266 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302267 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302268 if(rot) {
2269 rot->queueBuffer(fd, offset);
2270 fd = rot->getDstMemId();
2271 offset = rot->getDstOffset();
2272 }
2273 if(indexL != ovutils::OV_INVALID) {
2274 ovutils::eDest destL = (ovutils::eDest)indexL;
2275 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2276 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2277 if (!ov.queueBuffer(fd, offset, destL)) {
2278 ALOGE("%s: queueBuffer failed for display:%d",
2279 __FUNCTION__, mDpy);
2280 return false;
2281 }
2282 }
2283
2284 if(indexR != ovutils::OV_INVALID) {
2285 ovutils::eDest destR = (ovutils::eDest)indexR;
2286 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2287 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2288 if (!ov.queueBuffer(fd, offset, destR)) {
2289 ALOGE("%s: queueBuffer failed for display:%d",
2290 __FUNCTION__, mDpy);
2291 return false;
2292 }
2293 }
2294 }
2295 else{
2296 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002297 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302298 ovutils::eDest dest = pipe_info.index;
2299 if(dest == ovutils::OV_INVALID) {
2300 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002301 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302302 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002303
radhakrishnac9a67412013-09-25 17:40:42 +05302304 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2305 continue;
2306 }
2307
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002308 int fd = hnd->fd;
2309 uint32_t offset = (uint32_t)hnd->offset;
2310 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2311 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002312 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002313 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002314 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002315 }
2316
radhakrishnac9a67412013-09-25 17:40:42 +05302317 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2318 using pipe: %d", __FUNCTION__, layer,
2319 hnd, dest );
2320
radhakrishnac9a67412013-09-25 17:40:42 +05302321 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2322 if(rot) {
2323 if(!rot->queueBuffer(fd, offset))
2324 return false;
2325 fd = rot->getDstMemId();
2326 offset = rot->getDstOffset();
2327 }
2328
2329 if (!ov.queueBuffer(fd, offset, dest)) {
2330 ALOGE("%s: queueBuffer failed for display:%d ",
2331 __FUNCTION__, mDpy);
2332 return false;
2333 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002334 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002335
2336 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002337 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002338 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002339}
2340
Saurabh Shah88e4d272013-09-03 13:31:29 -07002341//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002342
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002343void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302344 hwc_display_contents_1_t* list){
2345 //if 4kx2k yuv layer is totally present in either in left half
2346 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302347 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302348 if(mCurrentFrame.fbZ >= 0) {
2349 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2350 index++) {
2351 if(!mCurrentFrame.isFBComposed[index]) {
2352 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2353 mdpNextZOrder++;
2354 }
2355 mdpNextZOrder++;
2356 hwc_layer_1_t* layer = &list->hwLayers[index];
2357 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302358 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302359 hwc_rect_t dst = layer->displayFrame;
2360 if((dst.left > lSplit) || (dst.right < lSplit)) {
2361 mCurrentFrame.mdpCount += 1;
2362 }
2363 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2364 mCurrentFrame.fbZ += 1;
2365 mdpNextZOrder++;
2366 }
2367 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002368 }
radhakrishnac9a67412013-09-25 17:40:42 +05302369 }
2370}
2371
Saurabh Shah88e4d272013-09-03 13:31:29 -07002372bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002373 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002374
Saurabh Shahc62f3982014-03-05 14:28:26 -08002375 const int lSplit = getLeftSplit(ctx, mDpy);
2376 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002377 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002378 pipe_info.lIndex = ovutils::OV_INVALID;
2379 pipe_info.rIndex = ovutils::OV_INVALID;
2380
Saurabh Shahc62f3982014-03-05 14:28:26 -08002381 Overlay::PipeSpecs pipeSpecs;
2382 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2383 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2384 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2385 pipeSpecs.dpy = mDpy;
2386 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2387 pipeSpecs.fb = false;
2388
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002389 // Acquire pipe only for the updating half
2390 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2391 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2392
2393 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002394 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002395 if(pipe_info.lIndex == ovutils::OV_INVALID)
2396 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002397 }
2398
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002399 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002400 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2401 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002402 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002403 return false;
2404 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002405
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002406 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002407}
2408
Saurabh Shah88e4d272013-09-03 13:31:29 -07002409bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002410 hwc_display_contents_1_t* list) {
2411 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002412
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002413 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002414
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002415 hwc_layer_1_t* layer = &list->hwLayers[index];
2416 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302417 hwc_rect_t dst = layer->displayFrame;
2418 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302419 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302420 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002421 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302422 continue;
2423 }
2424 }
2425 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002426 int mdpIndex = mCurrentFrame.layerToMDP[index];
2427 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002428 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002429 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002430 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002431
Saurabh Shahc62f3982014-03-05 14:28:26 -08002432 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2433 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2434 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002435 return false;
2436 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002437 }
2438 return true;
2439}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002440
radhakrishnac9a67412013-09-25 17:40:42 +05302441int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2442 PipeLayerPair& PipeLayerPair) {
2443 const int lSplit = getLeftSplit(ctx, mDpy);
2444 hwc_rect_t dst = layer->displayFrame;
2445 if((dst.left > lSplit)||(dst.right < lSplit)){
2446 MdpYUVPipeInfo& mdp_info =
2447 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2448 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302449 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302450 eDest lDest = mdp_info.lIndex;
2451 eDest rDest = mdp_info.rIndex;
2452
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002453 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302454 lDest, rDest, &PipeLayerPair.rot);
2455 }
2456 else{
2457 return configure(ctx, layer, PipeLayerPair);
2458 }
2459}
2460
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002461/*
2462 * Configures pipe(s) for MDP composition
2463 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002464int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002465 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002466 MdpPipeInfoSplit& mdp_info =
2467 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002468 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302469 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002470 eDest lDest = mdp_info.lIndex;
2471 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002472
2473 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002474 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002475
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002476 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002477 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002478}
2479
Saurabh Shah88e4d272013-09-03 13:31:29 -07002480bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002481
Raj Kamal4393eaa2014-06-06 13:45:20 +05302482 if(!isEnabled() or !mModeOn) {
2483 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302484 return true;
2485 }
2486
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002487 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002488 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002489 sHandleTimeout = true;
2490 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002491
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002492 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002493 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002494
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002495 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2496 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002497 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002498 if(mCurrentFrame.isFBComposed[i]) continue;
2499
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002500 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002501 private_handle_t *hnd = (private_handle_t *)layer->handle;
2502 if(!hnd) {
2503 ALOGE("%s handle null", __FUNCTION__);
2504 return false;
2505 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002506
2507 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2508 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002509 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002510
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002511 int mdpIndex = mCurrentFrame.layerToMDP[i];
2512
Raj Kamal389d6e32014-08-04 14:43:24 +05302513 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302514 {
2515 MdpYUVPipeInfo& pipe_info =
2516 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2517 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2518 ovutils::eDest indexL = pipe_info.lIndex;
2519 ovutils::eDest indexR = pipe_info.rIndex;
2520 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302521 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302522 if(rot) {
2523 rot->queueBuffer(fd, offset);
2524 fd = rot->getDstMemId();
2525 offset = rot->getDstOffset();
2526 }
2527 if(indexL != ovutils::OV_INVALID) {
2528 ovutils::eDest destL = (ovutils::eDest)indexL;
2529 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2530 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2531 if (!ov.queueBuffer(fd, offset, destL)) {
2532 ALOGE("%s: queueBuffer failed for display:%d",
2533 __FUNCTION__, mDpy);
2534 return false;
2535 }
2536 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002537
radhakrishnac9a67412013-09-25 17:40:42 +05302538 if(indexR != ovutils::OV_INVALID) {
2539 ovutils::eDest destR = (ovutils::eDest)indexR;
2540 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2541 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2542 if (!ov.queueBuffer(fd, offset, destR)) {
2543 ALOGE("%s: queueBuffer failed for display:%d",
2544 __FUNCTION__, mDpy);
2545 return false;
2546 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002547 }
2548 }
radhakrishnac9a67412013-09-25 17:40:42 +05302549 else{
2550 MdpPipeInfoSplit& pipe_info =
2551 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2552 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002553
radhakrishnac9a67412013-09-25 17:40:42 +05302554 ovutils::eDest indexL = pipe_info.lIndex;
2555 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002556
radhakrishnac9a67412013-09-25 17:40:42 +05302557 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002558 uint32_t offset = (uint32_t)hnd->offset;
2559 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2560 if (!mDpy && (index != -1)) {
2561 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2562 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002563 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002564 }
radhakrishnac9a67412013-09-25 17:40:42 +05302565
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002566 if(ctx->mAD->draw(ctx, fd, offset)) {
2567 fd = ctx->mAD->getDstFd();
2568 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002569 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002570
radhakrishnac9a67412013-09-25 17:40:42 +05302571 if(rot) {
2572 rot->queueBuffer(fd, offset);
2573 fd = rot->getDstMemId();
2574 offset = rot->getDstOffset();
2575 }
2576
2577 //************* play left mixer **********
2578 if(indexL != ovutils::OV_INVALID) {
2579 ovutils::eDest destL = (ovutils::eDest)indexL;
2580 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2581 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2582 if (!ov.queueBuffer(fd, offset, destL)) {
2583 ALOGE("%s: queueBuffer failed for left mixer",
2584 __FUNCTION__);
2585 return false;
2586 }
2587 }
2588
2589 //************* play right mixer **********
2590 if(indexR != ovutils::OV_INVALID) {
2591 ovutils::eDest destR = (ovutils::eDest)indexR;
2592 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2593 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2594 if (!ov.queueBuffer(fd, offset, destR)) {
2595 ALOGE("%s: queueBuffer failed for right mixer",
2596 __FUNCTION__);
2597 return false;
2598 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002599 }
2600 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002601
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002602 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2603 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002604
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002605 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002606}
Saurabh Shahab47c692014-02-12 18:45:57 -08002607
2608//================MDPCompSrcSplit==============================================
2609bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002610 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002611 private_handle_t *hnd = (private_handle_t *)layer->handle;
2612 hwc_rect_t dst = layer->displayFrame;
2613 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2614 pipe_info.lIndex = ovutils::OV_INVALID;
2615 pipe_info.rIndex = ovutils::OV_INVALID;
2616
2617 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2618 //should have a higher priority than the right one. Pipe priorities are
2619 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002620
Saurabh Shahc62f3982014-03-05 14:28:26 -08002621 Overlay::PipeSpecs pipeSpecs;
2622 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2623 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2624 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2625 pipeSpecs.dpy = mDpy;
2626 pipeSpecs.fb = false;
2627
Saurabh Shahab47c692014-02-12 18:45:57 -08002628 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002629 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002630 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002631 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002632 }
2633
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002634 /* Use 2 pipes IF
2635 a) Layer's crop width is > 2048 or
2636 b) Layer's dest width > 2048 or
2637 c) On primary, driver has indicated with caps to split always. This is
2638 based on an empirically derived value of panel height. Applied only
2639 if the layer's width is > mixer's width
2640 */
2641
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302642 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002643 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302644 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002645 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2646 const uint32_t dstWidth = dst.right - dst.left;
2647 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002648 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002649 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002650 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002651 crop.bottom - crop.top;
2652 //Approximation to actual clock, ignoring the common factors in pipe and
2653 //mixer cases like line_time
2654 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2655 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002656
Saurabh Shah05f4e222015-02-05 14:36:22 -08002657 const uint32_t downscale = getRotDownscale(ctx, layer);
2658 if(downscale) {
2659 cropWidth /= downscale;
2660 cropHeight /= downscale;
2661 }
2662
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002663 if(dstWidth > mdpHw.getMaxPipeWidth() or
2664 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002665 (primarySplitAlways and
2666 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002667 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002669 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002670 }
2671
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002672 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2673 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002674 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002675 }
2676 }
2677
2678 return true;
2679}
2680
Saurabh Shahab47c692014-02-12 18:45:57 -08002681int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2682 PipeLayerPair& PipeLayerPair) {
2683 private_handle_t *hnd = (private_handle_t *)layer->handle;
2684 if(!hnd) {
2685 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2686 return -1;
2687 }
2688 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2689 MdpPipeInfoSplit& mdp_info =
2690 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2691 Rotator **rot = &PipeLayerPair.rot;
2692 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002693 eDest lDest = mdp_info.lIndex;
2694 eDest rDest = mdp_info.rIndex;
2695 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2696 hwc_rect_t dst = layer->displayFrame;
2697 int transform = layer->transform;
2698 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002699 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002700 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002701 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2702
2703 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2704 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2705
2706 // Handle R/B swap
2707 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2708 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2709 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2710 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2711 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2712 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002713 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002714 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2715 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002716 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002717 /* Calculate the external display position based on MDP downscale,
2718 ActionSafe, and extorientation features. */
2719 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002720
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002721 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302722 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002723 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002724
2725 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2726 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002727 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002728 }
2729
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002730 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002731 (*rot) = ctx->mRotMgr->getNext();
2732 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002733 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002734 //If the video is using a single pipe, enable BWC
2735 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002736 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2737 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002738 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002739 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002740 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002741 ALOGE("%s: configRotator failed!", __FUNCTION__);
2742 return -1;
2743 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002744 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002745 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002746 }
2747
2748 //If 2 pipes being used, divide layer into half, crop and dst
2749 hwc_rect_t cropL = crop;
2750 hwc_rect_t cropR = crop;
2751 hwc_rect_t dstL = dst;
2752 hwc_rect_t dstR = dst;
2753 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2754 cropL.right = (crop.right + crop.left) / 2;
2755 cropR.left = cropL.right;
2756 sanitizeSourceCrop(cropL, cropR, hnd);
2757
Saurabh Shahb729b192014-08-15 18:04:24 -07002758 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002759 //Swap crops on H flip since 2 pipes are being used
2760 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2761 hwc_rect_t tmp = cropL;
2762 cropL = cropR;
2763 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002764 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002765 }
2766
Saurabh Shahb729b192014-08-15 18:04:24 -07002767 //cropSwap trick: If the src and dst widths are both odd, let us say
2768 //2507, then splitting both into half would cause left width to be 1253
2769 //and right 1254. If crop is swapped because of H flip, this will cause
2770 //left crop width to be 1254, whereas left dst width remains 1253, thus
2771 //inducing a scaling that is unaccounted for. To overcome that we add 1
2772 //to the dst width if there is a cropSwap. So if the original width was
2773 //2507, the left dst width will be 1254. Even if the original width was
2774 //even for ex: 2508, the left dst width will still remain 1254.
2775 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002776 dstR.left = dstL.right;
2777 }
2778
2779 //For the mdp, since either we are pre-rotating or MDP does flips
2780 orient = OVERLAY_TRANSFORM_0;
2781 transform = 0;
2782
2783 //configure left pipe
2784 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002785 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002786 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2787 (ovutils::eBlending) getBlending(layer->blending));
2788
2789 if(configMdp(ctx->mOverlay, pargL, orient,
2790 cropL, dstL, metadata, lDest) < 0) {
2791 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2792 return -1;
2793 }
2794 }
2795
2796 //configure right pipe
2797 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002798 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002799 static_cast<eRotFlags>(rotFlags),
2800 layer->planeAlpha,
2801 (ovutils::eBlending) getBlending(layer->blending));
2802 if(configMdp(ctx->mOverlay, pargR, orient,
2803 cropR, dstR, metadata, rDest) < 0) {
2804 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2805 return -1;
2806 }
2807 }
2808
2809 return 0;
2810}
2811
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002812bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2813 Locker::Autolock _l(ctx->mDrawLock);
2814 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2815 char path[MAX_SYSFS_FILE_PATH];
2816 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2817 int fd = open(path, O_RDONLY);
2818 if(fd < 0) {
2819 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2820 return -1;
2821 }
2822 char value[4];
2823 ssize_t size_read = read(fd, value, sizeof(value)-1);
2824 if(size_read <= 0) {
2825 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2826 close(fd);
2827 return -1;
2828 }
2829 close(fd);
2830 value[size_read] = '\0';
2831 return atoi(value);
2832}
2833
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002834int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2835 Locker::Autolock _l(ctx->mDrawLock);
2836 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2837 char path[MAX_SYSFS_FILE_PATH];
2838 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2839 int fd = open(path, O_WRONLY);
2840 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002841 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002842 return -1;
2843 }
2844 char value[4];
2845 snprintf(value, sizeof(value), "%d", (int)enable);
2846 ssize_t ret = write(fd, value, strlen(value));
2847 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002848 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002849 close(fd);
2850 return -1;
2851 }
2852 close(fd);
2853 sIsPartialUpdateActive = enable;
2854 return 0;
2855}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002856
2857bool MDPComp::loadPerfLib() {
2858 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2859 bool success = false;
2860 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2861 ALOGE("vendor library not set in ro.vendor.extension_library");
2862 return false;
2863 }
2864
2865 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
2866 if(sLibPerfHint) {
2867 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
2868 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
2869 if (!sPerfLockAcquire || !sPerfLockRelease) {
2870 ALOGE("Failed to load symbols for perfLock");
2871 dlclose(sLibPerfHint);
2872 sLibPerfHint = NULL;
2873 return false;
2874 }
2875 success = true;
2876 ALOGI("Successfully Loaded perf hint API's");
2877 } else {
2878 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
2879 }
2880 return success;
2881}
2882
2883void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2884 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
2885 return;
2886 }
2887 static int count = sPerfHintWindow;
2888 static int perflockFlag = 0;
2889
2890 /* Send hint to mpctl when single layer is updated
2891 * for a successful number of windows. Hint release
2892 * happens immediately upon multiple layer update.
2893 */
2894 if (onlyVideosUpdating(ctx, list)) {
2895 if(count) {
2896 count--;
2897 }
2898 } else {
2899 if (perflockFlag) {
2900 perflockFlag = 0;
2901 sPerfLockRelease(sPerfLockHandle);
2902 }
2903 count = sPerfHintWindow;
2904 }
2905 if (count == 0 && !perflockFlag) {
2906 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
2907 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
2908 &perfHint, sizeof(perfHint)/sizeof(int));
2909 if(sPerfLockHandle < 0) {
2910 ALOGE("Perf Lock Acquire Failed");
2911 } else {
2912 perflockFlag = 1;
2913 }
2914 }
2915}
2916
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002917}; //namespace
2918