blob: 569f5d1b8e34c960395c28d9a1b5a90c140758c5 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
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();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700220}
221
Raj Kamal4393eaa2014-06-06 13:45:20 +0530222void MDPComp::reset() {
223 sHandleTimeout = false;
224 mModeOn = false;
225}
226
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227void MDPComp::timeout_handler(void *udata) {
228 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
229
230 if(!ctx) {
231 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
232 return;
233 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530234
235 ctx->mDrawLock.lock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800236 // Handle timeout event only if the previous composition is MDP or MIXED.
237 if(!sHandleTimeout) {
238 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530239 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800240 return;
241 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700242 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700243 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530244 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700245 return;
246 }
247 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530248 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700249 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700250 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700251}
252
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700253void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
254 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800255 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700256 if(value > maxSupported) {
257 ALOGW("%s: Input exceeds max value supported. Setting to"
258 "max value: %d", __FUNCTION__, maxSupported);
259 }
260 sMaxPipesPerMixer = min(value, maxSupported);
261}
262
Saurabh Shah59562ff2014-09-30 16:13:12 -0700263void MDPComp::setIdleTimeout(const uint32_t& timeout) {
264 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
265
266 if(sIdleInvalidator) {
267 if(timeout <= ONE_REFRESH_PERIOD_MS) {
268 //If the specified timeout is < 1 draw cycle worth, "virtually"
269 //disable idle timeout. The ideal way for clients to disable
270 //timeout is to set it to 0
271 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
272 ALOGI("Disabled idle timeout");
273 return;
274 }
275 sIdleInvalidator->setIdleTimeout(timeout);
276 ALOGI("Idle timeout set to %u", timeout);
277 } else {
278 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
279 }
280}
281
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800282void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283 hwc_display_contents_1_t* list) {
284 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800285
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800287 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800288 if(!mCurrentFrame.isFBComposed[index]) {
289 layerProp[index].mFlags |= HWC_MDPCOMP;
290 layer->compositionType = HWC_OVERLAY;
291 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800292 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700293 /* Drop the layer when its already present in FB OR when it lies
294 * outside frame's ROI */
295 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700297 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800298 }
299 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700300}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500301
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800302void MDPComp::setRedraw(hwc_context_t *ctx,
303 hwc_display_contents_1_t* list) {
304 mCurrentFrame.needsRedraw = false;
305 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
306 (list->flags & HWC_GEOMETRY_CHANGED) ||
307 isSkipPresent(ctx, mDpy)) {
308 mCurrentFrame.needsRedraw = true;
309 }
310}
311
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800312MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700313 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700314 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316
Saurabh Shahaa236822013-04-24 18:07:26 -0700317void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700318 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800319 if(mdpToLayer[i].pipeInfo) {
320 delete mdpToLayer[i].pipeInfo;
321 mdpToLayer[i].pipeInfo = NULL;
322 //We dont own the rotator
323 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800324 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800325 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800326
327 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
328 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700329 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330
Saurabh Shahaa236822013-04-24 18:07:26 -0700331 layerCount = numLayers;
332 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800333 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700334 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800335 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336}
337
Saurabh Shahaa236822013-04-24 18:07:26 -0700338void MDPComp::FrameInfo::map() {
339 // populate layer and MDP maps
340 int mdpIdx = 0;
341 for(int idx = 0; idx < layerCount; idx++) {
342 if(!isFBComposed[idx]) {
343 mdpToLayer[mdpIdx].listIndex = idx;
344 layerToMDP[idx] = mdpIdx++;
345 }
346 }
347}
348
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800349MDPComp::LayerCache::LayerCache() {
350 reset();
351}
352
353void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700354 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530355 memset(&isFBComposed, true, sizeof(isFBComposed));
356 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700358}
359
360void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530361 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700362 for(int i = 0; i < numAppLayers; i++) {
363 hnd[i] = list->hwLayers[i].handle;
364 }
365}
366
367void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700368 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530369 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
370 memcpy(&drop, &curFrame.drop, sizeof(drop));
371}
372
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800373bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
374 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530375 if(layerCount != curFrame.layerCount)
376 return false;
377 for(int i = 0; i < curFrame.layerCount; i++) {
378 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
379 (curFrame.drop[i] != drop[i])) {
380 return false;
381 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800382 if(curFrame.isFBComposed[i] &&
383 (hnd[i] != list->hwLayers[i].handle)){
384 return false;
385 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530386 }
387 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800388}
389
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700390bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
391 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800392 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700393 (not isValidDimension(ctx,layer))
394 //More conditions here, SKIP, sRGB+Blend etc
395 ) {
396 return false;
397 }
398 return true;
399}
400
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530401bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800402 private_handle_t *hnd = (private_handle_t *)layer->handle;
403
404 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700405 if (layer->flags & HWC_COLOR_FILL) {
406 // Color layer
407 return true;
408 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700409 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return false;
411 }
412
Naseer Ahmede850a802013-09-06 13:12:52 -0400413 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400414 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400415 return false;
416
Saurabh Shah62e1d732013-09-17 10:44:05 -0700417 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700418 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700419 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700420 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
421 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700422 int dst_w = dst.right - dst.left;
423 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800424 float w_scale = ((float)crop_w / (float)dst_w);
425 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530426 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800428 /* Workaround for MDP HW limitation in DSI command mode panels where
429 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
430 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530431 * There also is a HW limilation in MDP, minimum block size is 2x2
432 * Fallback to GPU if height is less than 2.
433 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700434 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800435 return false;
436
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800437 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530438 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800439 const float w_dscale = w_scale;
440 const float h_dscale = h_scale;
441
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800442 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700443
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530444 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700445 /* On targets that doesnt support Decimation (eg.,8x26)
446 * maximum downscale support is overlay pipe downscale.
447 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800448 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530449 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700450 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800451 return false;
452 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700453 // Decimation on macrotile format layers is not supported.
454 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530455 /* Bail out if
456 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700457 * 2. exceeds maximum downscale limit
458 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800459 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530460 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700461 w_dscale > maxMDPDownscale ||
462 h_dscale > maxMDPDownscale) {
463 return false;
464 }
465 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800466 return false;
467 }
468 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700469 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700470 return false;
471 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700472 }
473
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800474 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530475 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800476 const float w_uscale = 1.0f / w_scale;
477 const float h_uscale = 1.0f / h_scale;
478
479 if(w_uscale > upscale || h_uscale > upscale)
480 return false;
481 }
482
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800483 return true;
484}
485
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800486bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700487 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800488
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800489 if(!isEnabled()) {
490 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700491 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530492 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530493 qdutils::MDPVersion::getInstance().is8x16() ||
494 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800495 ctx->mVideoTransFlag &&
496 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700497 //1 Padding round to shift pipes across mixers
498 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
499 __FUNCTION__);
500 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700501 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
502 /* TODO: freeing up all the resources only for the targets having total
503 number of pipes < 8. Need to analyze number of VIG pipes used
504 for primary in previous draw cycle and accordingly decide
505 whether to fall back to full GPU comp or video only comp
506 */
507 if(isSecondaryConfiguring(ctx)) {
508 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
509 __FUNCTION__);
510 ret = false;
511 } else if(ctx->isPaddingRound) {
512 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
513 __FUNCTION__,mDpy);
514 ret = false;
515 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800516 } else if (ctx->isDMAStateChanging) {
517 // Bail out if a padding round has been invoked in order to switch DMA
518 // state to block mode. We need this to cater for the case when a layer
519 // requires rotation in the current frame.
520 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
521 __FUNCTION__);
522 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700523 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800524
Saurabh Shahaa236822013-04-24 18:07:26 -0700525 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800526}
527
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
529 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
530 fbRect = getIntersection(fbRect, roi);
531}
532
533/* 1) Identify layers that are not visible or lying outside the updating ROI and
534 * drop them from composition.
535 * 2) If we have a scaling layer which needs cropping against generated
536 * ROI, reset ROI to full resolution. */
537bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
538 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700539 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800541
542 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800543 if(!isValidRect(visibleRect)) {
544 mCurrentFrame.drop[i] = true;
545 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800546 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800547 }
548
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700549 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800551 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700552
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700553 if(!isValidRect(res)) {
554 mCurrentFrame.drop[i] = true;
555 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800556 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700557 /* Reset frame ROI when any layer which needs scaling also needs ROI
558 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800559 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800560 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700561 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
562 mCurrentFrame.dropCount = 0;
563 return false;
564 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800565
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800566 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530567 if (layer->blending == HWC_BLENDING_NONE &&
568 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800569 visibleRect = deductRect(visibleRect, res);
570 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700571 }
572 return true;
573}
574
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
576 * are updating. If DirtyRegion is applicable, calculate it by accounting all
577 * the changing layer's dirtyRegion. */
578void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
579 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700580 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800581 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700582 return;
583
584 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800585 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
586 (int)ctx->dpyAttr[mDpy].yres};
587
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700588 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800589 hwc_layer_1_t* layer = &list->hwLayers[index];
590 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800591 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700592 hwc_rect_t dst = layer->displayFrame;
593 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800594
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800595#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800596 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700597 {
598 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
599 int x_off = dst.left - src.left;
600 int y_off = dst.top - src.top;
601 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
602 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800603#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800604
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800605 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700606 }
607 }
608
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800609 /* No layer is updating. Still SF wants a refresh.*/
610 if(!isValidRect(roi))
611 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800612
613 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800614 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800615
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800616 ctx->listStats[mDpy].lRoi = roi;
617 if(!validateAndApplyROI(ctx, list))
618 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700619
620 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800621 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
622 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
623}
624
625void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
626 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
627 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
628
629 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
630 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
631 fbRect = getUnion(l_fbRect, r_fbRect);
632}
633/* 1) Identify layers that are not visible or lying outside BOTH the updating
634 * ROI's and drop them from composition. If a layer is spanning across both
635 * the halves of the screen but needed by only ROI, the non-contributing
636 * half will not be programmed for MDP.
637 * 2) If we have a scaling layer which needs cropping against generated
638 * ROI, reset ROI to full resolution. */
639bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
640 hwc_display_contents_1_t* list) {
641
642 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
643
644 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
645 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
646
647 for(int i = numAppLayers - 1; i >= 0; i--){
648 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
649 {
650 mCurrentFrame.drop[i] = true;
651 mCurrentFrame.dropCount++;
652 continue;
653 }
654
655 const hwc_layer_1_t* layer = &list->hwLayers[i];
656 hwc_rect_t dstRect = layer->displayFrame;
657
658 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
659 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
660 hwc_rect_t res = getUnion(l_res, r_res);
661
662 if(!isValidRect(l_res) && !isValidRect(r_res)) {
663 mCurrentFrame.drop[i] = true;
664 mCurrentFrame.dropCount++;
665 } else {
666 /* Reset frame ROI when any layer which needs scaling also needs ROI
667 * cropping */
668 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
669 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
670 mCurrentFrame.dropCount = 0;
671 return false;
672 }
673
radhakrishna4efbdd62014-11-03 13:19:27 +0530674 if (layer->blending == HWC_BLENDING_NONE &&
675 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800676 visibleRectL = deductRect(visibleRectL, l_res);
677 visibleRectR = deductRect(visibleRectR, r_res);
678 }
679 }
680 }
681 return true;
682}
683/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
684 * are updating. If DirtyRegion is applicable, calculate it by accounting all
685 * the changing layer's dirtyRegion. */
686void MDPCompSplit::generateROI(hwc_context_t *ctx,
687 hwc_display_contents_1_t* list) {
688 if(!canPartialUpdate(ctx, list))
689 return;
690
691 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
692 int lSplit = getLeftSplit(ctx, mDpy);
693
694 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
695 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
696
697 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
698 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
699
700 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
701 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
702
703 for(int index = 0; index < numAppLayers; index++ ) {
704 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800705 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800706 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800707 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700708 hwc_rect_t dst = layer->displayFrame;
709 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800710
711#ifdef QCOM_BSP
712 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700713 {
714 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
715 int x_off = dst.left - src.left;
716 int y_off = dst.top - src.top;
717 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
718 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800719#endif
720
721 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
722 if(isValidRect(l_dst))
723 l_roi = getUnion(l_roi, l_dst);
724
725 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
726 if(isValidRect(r_dst))
727 r_roi = getUnion(r_roi, r_dst);
728 }
729 }
730
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700731 /* For panels that cannot accept commands in both the interfaces, we cannot
732 * send two ROI's (for each half). We merge them into single ROI and split
733 * them across lSplit for MDP mixer use. The ROI's will be merged again
734 * finally before udpating the panel in the driver. */
735 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
736 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
737 l_roi = getIntersection(temp_roi, l_frame);
738 r_roi = getIntersection(temp_roi, r_frame);
739 }
740
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800741 /* No layer is updating. Still SF wants a refresh. */
742 if(!isValidRect(l_roi) && !isValidRect(r_roi))
743 return;
744
745 l_roi = getSanitizeROI(l_roi, l_frame);
746 r_roi = getSanitizeROI(r_roi, r_frame);
747
748 ctx->listStats[mDpy].lRoi = l_roi;
749 ctx->listStats[mDpy].rRoi = r_roi;
750
751 if(!validateAndApplyROI(ctx, list))
752 resetROI(ctx, mDpy);
753
754 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
755 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
756 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
757 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
758 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
759 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700760}
761
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800762/* Checks for conditions where all the layers marked for MDP comp cannot be
763 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800764bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800765 hwc_display_contents_1_t* list){
766
Saurabh Shahaa236822013-04-24 18:07:26 -0700767 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800768
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700769 // Fall back to video only composition, if AIV video mode is enabled
770 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700771 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
772 __FUNCTION__, mDpy);
773 return false;
774 }
775
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530776 /* No Idle fall back if secure display or secure RGB layers are present
777 * or if there is only a single layer being composed */
778 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
779 !ctx->listStats[mDpy].secureRGBCount &&
780 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700781 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
782 return false;
783 }
784
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800785 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700786 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
787 __FUNCTION__,
788 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800789 return false;
790 }
791
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700792 // if secondary is configuring or Padding round, fall back to video only
793 // composition and release all assigned non VIG pipes from primary.
794 if(isSecondaryConfiguring(ctx)) {
795 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
796 __FUNCTION__);
797 return false;
798 } else if(ctx->isPaddingRound) {
799 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
800 __FUNCTION__,mDpy);
801 return false;
802 }
803
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700804 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800805 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700806 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800807 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
808 return false;
809 }
810
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800811 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800812 hwc_layer_1_t* layer = &list->hwLayers[i];
813 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800814
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800815 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700816 if(!canUseRotator(ctx, mDpy)) {
817 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
818 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700819 return false;
820 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800821 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530822
823 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
824 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800825 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700826 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530827 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
828 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
829 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800830 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700831
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700832 if(ctx->mAD->isDoable()) {
833 return false;
834 }
835
Saurabh Shahaa236822013-04-24 18:07:26 -0700836 //If all above hard conditions are met we can do full or partial MDP comp.
837 bool ret = false;
838 if(fullMDPComp(ctx, list)) {
839 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840 } else if(fullMDPCompWithPTOR(ctx, list)) {
841 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700842 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700843 ret = true;
844 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530845
Saurabh Shahaa236822013-04-24 18:07:26 -0700846 return ret;
847}
848
849bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700850
851 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
852 return false;
853
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700854 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
855 for(int i = 0; i < numAppLayers; i++) {
856 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700857 if(not mCurrentFrame.drop[i] and
858 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700859 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
860 return false;
861 }
862 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800863
Saurabh Shahaa236822013-04-24 18:07:26 -0700864 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700865 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
866 sizeof(mCurrentFrame.isFBComposed));
867 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
868 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700869
Raj Kamal389d6e32014-08-04 14:43:24 +0530870 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800871 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530872 }
873
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800874 if(!postHeuristicsHandling(ctx, list)) {
875 ALOGD_IF(isDebug(), "post heuristic handling failed");
876 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700877 return false;
878 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700879 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
880 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700881 return true;
882}
883
Sushil Chauhandefd3522014-05-13 18:17:12 -0700884/* Full MDP Composition with Peripheral Tiny Overlap Removal.
885 * MDP bandwidth limitations can be avoided, if the overlap region
886 * covered by the smallest layer at a higher z-order, gets composed
887 * by Copybit on a render buffer, which can be queued to MDP.
888 */
889bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
890 hwc_display_contents_1_t* list) {
891
892 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
893 const int stagesForMDP = min(sMaxPipesPerMixer,
894 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
895
896 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700897 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700898 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
899 return false;
900 }
901
902 // Frame level checks
903 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
904 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
905 isSecurePresent(ctx, mDpy)) {
906 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
907 return false;
908 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700909 // MDP comp checks
910 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700912 if(not isSupportedForMDPComp(ctx, layer)) {
913 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
914 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 }
916 }
917
Sushil Chauhandefd3522014-05-13 18:17:12 -0700918 /* We cannot use this composition mode, if:
919 1. A below layer needs scaling.
920 2. Overlap is not peripheral to display.
921 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700922 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700923 */
924
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700925 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
926 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
927 memset(overlapRect, 0, sizeof(overlapRect));
928 int layerPixelCount, minPixelCount = 0;
929 int numPTORLayersFound = 0;
930 for (int i = numAppLayers-1; (i >= 0 &&
931 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700932 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700933 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700934 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700935 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
936 // PTOR layer should be peripheral and cannot have transform
937 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
938 has90Transform(layer)) {
939 continue;
940 }
941 if((3 * (layerPixelCount + minPixelCount)) >
942 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
943 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
944 continue;
945 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700946 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700947 for (int j = i-1; j >= 0; j--) {
948 // Check if the layers below this layer qualifies for PTOR comp
949 hwc_layer_1_t* layer = &list->hwLayers[j];
950 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700951 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700952 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700953 if (isValidRect(getIntersection(dispFrame, disFrame))) {
954 if (has90Transform(layer) || needsScaling(layer)) {
955 found = false;
956 break;
957 }
958 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700959 }
960 }
961 // Store the minLayer Index
962 if(found) {
963 minLayerIndex[numPTORLayersFound] = i;
964 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
965 minPixelCount += layerPixelCount;
966 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700967 }
968 }
969
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700970 // No overlap layers
971 if (!numPTORLayersFound)
972 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700973
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700974 // Store the displayFrame and the sourceCrops of the layers
975 hwc_rect_t displayFrame[numAppLayers];
976 hwc_rect_t sourceCrop[numAppLayers];
977 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700978 hwc_layer_1_t* layer = &list->hwLayers[i];
979 displayFrame[i] = layer->displayFrame;
980 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700981 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700982
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530983 /**
984 * It's possible that 2 PTOR layers might have overlapping.
985 * In such case, remove the intersection(again if peripheral)
986 * from the lower PTOR layer to avoid overlapping.
987 * If intersection is not on peripheral then compromise
988 * by reducing number of PTOR layers.
989 **/
990 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
991 if(isValidRect(commonRect)) {
992 overlapRect[1] = deductRect(overlapRect[1], commonRect);
993 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
994 }
995
996 ctx->mPtorInfo.count = numPTORLayersFound;
997 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
998 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
999 }
1000
1001 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1002 // reset PTOR
1003 ctx->mPtorInfo.count = 0;
1004 if(isValidRect(commonRect)) {
1005 // If PTORs are intersecting restore displayframe of PTOR[1]
1006 // before returning, as we have modified it above.
1007 list->hwLayers[minLayerIndex[1]].displayFrame =
1008 displayFrame[minLayerIndex[1]];
1009 }
1010 return false;
1011 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001012 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1013 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1014
Xu Yangcda012c2014-07-30 21:57:21 +08001015 // Store the blending mode, planeAlpha, and transform of PTOR layers
1016 int32_t blending[numPTORLayersFound];
1017 uint8_t planeAlpha[numPTORLayersFound];
1018 uint32_t transform[numPTORLayersFound];
1019
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001020 for(int j = 0; j < numPTORLayersFound; j++) {
1021 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001022
1023 // Update src crop of PTOR layer
1024 hwc_layer_1_t* layer = &list->hwLayers[index];
1025 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1026 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1027 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1028 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1029
1030 // Store & update w, h, format of PTOR layer
1031 private_handle_t *hnd = (private_handle_t *)layer->handle;
1032 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1033 layerWhf[j] = whf;
1034 hnd->width = renderBuf->width;
1035 hnd->height = renderBuf->height;
1036 hnd->format = renderBuf->format;
1037
Xu Yangcda012c2014-07-30 21:57:21 +08001038 // Store & update blending mode, planeAlpha and transform of PTOR layer
1039 blending[j] = layer->blending;
1040 planeAlpha[j] = layer->planeAlpha;
1041 transform[j] = layer->transform;
1042 layer->blending = HWC_BLENDING_NONE;
1043 layer->planeAlpha = 0xFF;
1044 layer->transform = 0;
1045
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001046 // Remove overlap from crop & displayFrame of below layers
1047 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001048 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001049 if(!isValidRect(getIntersection(layer->displayFrame,
1050 overlapRect[j]))) {
1051 continue;
1052 }
1053 // Update layer attributes
1054 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1055 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301056 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001057 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1058 layer->transform);
1059 layer->sourceCropf.left = (float)srcCrop.left;
1060 layer->sourceCropf.top = (float)srcCrop.top;
1061 layer->sourceCropf.right = (float)srcCrop.right;
1062 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1063 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001064 }
1065
1066 mCurrentFrame.mdpCount = numAppLayers;
1067 mCurrentFrame.fbCount = 0;
1068 mCurrentFrame.fbZ = -1;
1069
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301070 for (int j = 0; j < numAppLayers; j++) {
1071 if(isValidRect(list->hwLayers[j].displayFrame)) {
1072 mCurrentFrame.isFBComposed[j] = false;
1073 } else {
1074 mCurrentFrame.mdpCount--;
1075 mCurrentFrame.drop[j] = true;
1076 }
1077 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001078
1079 bool result = postHeuristicsHandling(ctx, list);
1080
1081 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001082 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001083 hwc_layer_1_t* layer = &list->hwLayers[i];
1084 layer->displayFrame = displayFrame[i];
1085 layer->sourceCropf.left = (float)sourceCrop[i].left;
1086 layer->sourceCropf.top = (float)sourceCrop[i].top;
1087 layer->sourceCropf.right = (float)sourceCrop[i].right;
1088 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1089 }
1090
Xu Yangcda012c2014-07-30 21:57:21 +08001091 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001092 for (int i = 0; i < numPTORLayersFound; i++) {
1093 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001094 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001095 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1096 hnd->width = layerWhf[i].w;
1097 hnd->height = layerWhf[i].h;
1098 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001099 layer->blending = blending[i];
1100 layer->planeAlpha = planeAlpha[i];
1101 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001102 }
1103
Sushil Chauhandefd3522014-05-13 18:17:12 -07001104 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001105 // reset PTOR
1106 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001107 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001108 } else {
1109 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1110 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001111 }
1112
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001113 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1114 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001115 return result;
1116}
1117
Saurabh Shahaa236822013-04-24 18:07:26 -07001118bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1119{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001120 if(!sEnableMixedMode) {
1121 //Mixed mode is disabled. No need to even try caching.
1122 return false;
1123 }
1124
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001125 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001126 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001127 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001128 cacheBasedComp(ctx, list);
1129 } else {
1130 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001131 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001132 }
1133
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001134 return ret;
1135}
1136
1137bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1138 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001139 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1140 return false;
1141
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001142 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001143 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001144 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001145
1146 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1147 for(int i = 0; i < numAppLayers; i++) {
1148 if(!mCurrentFrame.isFBComposed[i]) {
1149 hwc_layer_1_t* layer = &list->hwLayers[i];
1150 if(not isSupportedForMDPComp(ctx, layer)) {
1151 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1152 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001153 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001154 return false;
1155 }
1156 }
1157 }
1158
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001159 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001160 /* mark secure RGB layers for MDP comp */
1161 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301162 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001163 if(!ret) {
1164 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001165 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001166 return false;
1167 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001168
1169 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001170
Raj Kamal389d6e32014-08-04 14:43:24 +05301171 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001172 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301173 }
1174
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001175 if(!postHeuristicsHandling(ctx, list)) {
1176 ALOGD_IF(isDebug(), "post heuristic handling failed");
1177 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001178 return false;
1179 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001180 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1181 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001182
Saurabh Shahaa236822013-04-24 18:07:26 -07001183 return true;
1184}
1185
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001186bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001187 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001188 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1189 return false;
1190
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001191 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001192 return false;
1193 }
1194
Saurabh Shahb772ae32013-11-18 15:40:02 -08001195 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001196 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1197 const int stagesForMDP = min(sMaxPipesPerMixer,
1198 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001199
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001200 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1201 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1202 int lastMDPSupportedIndex = numAppLayers;
1203 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001204
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001205 //Find the minimum MDP batch size
1206 for(int i = 0; i < numAppLayers;i++) {
1207 if(mCurrentFrame.drop[i]) {
1208 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001209 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001210 }
1211 hwc_layer_1_t* layer = &list->hwLayers[i];
1212 if(not isSupportedForMDPComp(ctx, layer)) {
1213 lastMDPSupportedIndex = i;
1214 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1215 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001216 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001217 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001218 }
1219
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001220 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1221 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1222 mCurrentFrame.dropCount);
1223
1224 //Start at a point where the fb batch should at least have 2 layers, for
1225 //this mode to be justified.
1226 while(fbBatchSize < 2) {
1227 ++fbBatchSize;
1228 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001229 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001230
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001231 //If there are no layers for MDP, this mode doesnt make sense.
1232 if(mdpBatchSize < 1) {
1233 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1234 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001235 return false;
1236 }
1237
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001238 mCurrentFrame.reset(numAppLayers);
1239
1240 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1241 while(mdpBatchSize > 0) {
1242 //Mark layers for MDP comp
1243 int mdpBatchLeft = mdpBatchSize;
1244 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1245 if(mCurrentFrame.drop[i]) {
1246 continue;
1247 }
1248 mCurrentFrame.isFBComposed[i] = false;
1249 --mdpBatchLeft;
1250 }
1251
1252 mCurrentFrame.fbZ = mdpBatchSize;
1253 mCurrentFrame.fbCount = fbBatchSize;
1254 mCurrentFrame.mdpCount = mdpBatchSize;
1255
1256 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1257 __FUNCTION__, mdpBatchSize, fbBatchSize,
1258 mCurrentFrame.dropCount);
1259
1260 if(postHeuristicsHandling(ctx, list)) {
1261 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001262 __FUNCTION__);
1263 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1264 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001265 return true;
1266 }
1267
1268 reset(ctx);
1269 --mdpBatchSize;
1270 ++fbBatchSize;
1271 }
1272
1273 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001274}
1275
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001276bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301277 if(mDpy or isSecurePresent(ctx, mDpy) or
1278 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001279 return false;
1280 }
1281 return true;
1282}
1283
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001284bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1285 hwc_display_contents_1_t* list){
1286 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1287 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001288 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001289 return false;
1290 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001291 if(ctx->listStats[mDpy].secureUI)
1292 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001293 return true;
1294}
1295
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001296bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1297 hwc_display_contents_1_t* list) {
1298 const bool secureOnly = true;
1299 return videoOnlyComp(ctx, list, not secureOnly) or
1300 videoOnlyComp(ctx, list, secureOnly);
1301}
1302
1303bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001304 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001305 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1306 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301307
Saurabh Shahaa236822013-04-24 18:07:26 -07001308 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301309 if(!isSecurePresent(ctx, mDpy)) {
1310 /* Bail out if we are processing only secured video layers
1311 * and we dont have any */
1312 if(secureOnly) {
1313 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1314 return false;
1315 }
1316 /* No Idle fall back for secure video layers and if there is only
1317 * single layer being composed. */
1318 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1319 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1320 return false;
1321 }
1322 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001323
Saurabh Shahaa236822013-04-24 18:07:26 -07001324 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001325 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001326 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001327 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001328
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001329 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1330 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001331 return false;
1332 }
1333
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001334 if(mCurrentFrame.fbCount)
1335 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001336
Raj Kamal389d6e32014-08-04 14:43:24 +05301337 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001338 adjustForSourceSplit(ctx, list);
1339 }
1340
1341 if(!postHeuristicsHandling(ctx, list)) {
1342 ALOGD_IF(isDebug(), "post heuristic handling failed");
1343 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001344 return false;
1345 }
1346
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001347 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1348 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001349 return true;
1350}
1351
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001352/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1353bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1354 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001355 // Fall back to video only composition, if AIV video mode is enabled
1356 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001357 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1358 __FUNCTION__, mDpy);
1359 return false;
1360 }
1361
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001362 const bool secureOnly = true;
1363 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1364 mdpOnlyLayersComp(ctx, list, secureOnly);
1365
1366}
1367
1368bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1369 hwc_display_contents_1_t* list, bool secureOnly) {
1370
1371 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1372 return false;
1373
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301374 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1375 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1376 /* Bail out if we are processing only secured video/ui layers
1377 * and we dont have any */
1378 if(secureOnly) {
1379 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1380 return false;
1381 }
1382 /* No Idle fall back for secure video/ui layers and if there is only
1383 * single layer being composed. */
1384 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1385 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1386 return false;
1387 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001388 }
1389
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001390 mCurrentFrame.reset(numAppLayers);
1391 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1392
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001393 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001394 /* mark secure RGB layers for MDP comp */
1395 updateSecureRGB(ctx, list);
1396
1397 if(mCurrentFrame.mdpCount == 0) {
1398 reset(ctx);
1399 return false;
1400 }
1401
1402 /* find the maximum batch of layers to be marked for framebuffer */
1403 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1404 if(!ret) {
1405 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1406 reset(ctx);
1407 return false;
1408 }
1409
1410 if(sEnableYUVsplit){
1411 adjustForSourceSplit(ctx, list);
1412 }
1413
1414 if(!postHeuristicsHandling(ctx, list)) {
1415 ALOGD_IF(isDebug(), "post heuristic handling failed");
1416 reset(ctx);
1417 return false;
1418 }
1419
1420 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1421 __FUNCTION__);
1422 return true;
1423}
1424
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001425/* Checks for conditions where YUV layers cannot be bypassed */
1426bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001427 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001428 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001429 return false;
1430 }
1431
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001432 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001433 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1434 return false;
1435 }
1436
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001437 if(isSecuring(ctx, layer)) {
1438 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1439 return false;
1440 }
1441
Saurabh Shah4fdde762013-04-30 18:47:33 -07001442 if(!isValidDimension(ctx, layer)) {
1443 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1444 __FUNCTION__);
1445 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001446 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001447
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001448 if(layer->planeAlpha < 0xFF) {
1449 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1450 in video only mode",
1451 __FUNCTION__);
1452 return false;
1453 }
1454
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001455 return true;
1456}
1457
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001458/* Checks for conditions where Secure RGB layers cannot be bypassed */
1459bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1460 if(isSkipLayer(layer)) {
1461 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1462 __FUNCTION__, mDpy);
1463 return false;
1464 }
1465
1466 if(isSecuring(ctx, layer)) {
1467 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1468 return false;
1469 }
1470
1471 if(not isSupportedForMDPComp(ctx, layer)) {
1472 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1473 __FUNCTION__);
1474 return false;
1475 }
1476 return true;
1477}
1478
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301479/* starts at fromIndex and check for each layer to find
1480 * if it it has overlapping with any Updating layer above it in zorder
1481 * till the end of the batch. returns true if it finds any intersection */
1482bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1483 int fromIndex, int toIndex) {
1484 for(int i = fromIndex; i < toIndex; i++) {
1485 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1486 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1487 return false;
1488 }
1489 }
1490 }
1491 return true;
1492}
1493
1494/* Checks if given layer at targetLayerIndex has any
1495 * intersection with all the updating layers in beween
1496 * fromIndex and toIndex. Returns true if it finds intersectiion */
1497bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1498 int fromIndex, int toIndex, int targetLayerIndex) {
1499 for(int i = fromIndex; i <= toIndex; i++) {
1500 if(!mCurrentFrame.isFBComposed[i]) {
1501 if(areLayersIntersecting(&list->hwLayers[i],
1502 &list->hwLayers[targetLayerIndex])) {
1503 return true;
1504 }
1505 }
1506 }
1507 return false;
1508}
1509
1510int MDPComp::getBatch(hwc_display_contents_1_t* list,
1511 int& maxBatchStart, int& maxBatchEnd,
1512 int& maxBatchCount) {
1513 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301514 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001515 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301516 while (i < mCurrentFrame.layerCount) {
1517 int batchCount = 0;
1518 int batchStart = i;
1519 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001520 /* Adjust batch Z order with the dropped layers so far */
1521 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301522 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301523 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301524 while(i < mCurrentFrame.layerCount) {
1525 if(!mCurrentFrame.isFBComposed[i]) {
1526 if(!batchCount) {
1527 i++;
1528 break;
1529 }
1530 updatingLayersAbove++;
1531 i++;
1532 continue;
1533 } else {
1534 if(mCurrentFrame.drop[i]) {
1535 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001536 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301537 continue;
1538 } else if(updatingLayersAbove <= 0) {
1539 batchCount++;
1540 batchEnd = i;
1541 i++;
1542 continue;
1543 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1544
1545 // We have a valid updating layer already. If layer-i not
1546 // have overlapping with all updating layers in between
1547 // batch-start and i, then we can add layer i to batch.
1548 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1549 batchCount++;
1550 batchEnd = i;
1551 i++;
1552 continue;
1553 } else if(canPushBatchToTop(list, batchStart, i)) {
1554 //If All the non-updating layers with in this batch
1555 //does not have intersection with the updating layers
1556 //above in z-order, then we can safely move the batch to
1557 //higher z-order. Increment fbZ as it is moving up.
1558 if( firstZReverseIndex < 0) {
1559 firstZReverseIndex = i;
1560 }
1561 batchCount++;
1562 batchEnd = i;
1563 fbZ += updatingLayersAbove;
1564 i++;
1565 updatingLayersAbove = 0;
1566 continue;
1567 } else {
1568 //both failed.start the loop again from here.
1569 if(firstZReverseIndex >= 0) {
1570 i = firstZReverseIndex;
1571 }
1572 break;
1573 }
1574 }
1575 }
1576 }
1577 if(batchCount > maxBatchCount) {
1578 maxBatchCount = batchCount;
1579 maxBatchStart = batchStart;
1580 maxBatchEnd = batchEnd;
1581 fbZOrder = fbZ;
1582 }
1583 }
1584 return fbZOrder;
1585}
1586
1587bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1588 hwc_display_contents_1_t* list) {
1589 /* Idea is to keep as many non-updating(cached) layers in FB and
1590 * send rest of them through MDP. This is done in 2 steps.
1591 * 1. Find the maximum contiguous batch of non-updating layers.
1592 * 2. See if we can improve this batch size for caching by adding
1593 * opaque layers around the batch, if they don't have
1594 * any overlapping with the updating layers in between.
1595 * NEVER mark an updating layer for caching.
1596 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001597
1598 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001599 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001600 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301601 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001603 /* Nothing is cached. No batching needed */
1604 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001605 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001606 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001607
1608 /* No MDP comp layers, try to use other comp modes */
1609 if(mCurrentFrame.mdpCount == 0) {
1610 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001611 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001612
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301613 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001614
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301615 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001617 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001618 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301619 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001620 if(!mCurrentFrame.drop[i]){
1621 //If an unsupported layer is being attempted to
1622 //be pulled out we should fail
1623 if(not isSupportedForMDPComp(ctx, layer)) {
1624 return false;
1625 }
1626 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001627 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001628 }
1629 }
1630
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301631 // update the frame data
1632 mCurrentFrame.fbZ = fbZ;
1633 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001634 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001635 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001636
1637 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301638 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001639
1640 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001641}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001642
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001643void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001644 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001645 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001646 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001647
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001648 for(int i = 0; i < numAppLayers; i++) {
1649 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001650 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001651 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001652 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001653 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001654 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001655 }
1656 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001657
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001658 frame.fbCount = fbCount;
1659 frame.mdpCount = frame.layerCount - frame.fbCount
1660 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001661
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001662 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1663 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664}
1665
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001666// drop other non-AIV layers from external display list.
1667void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001668 hwc_display_contents_1_t* list) {
1669 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1670 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001671 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001672 mCurrentFrame.dropCount++;
1673 mCurrentFrame.drop[i] = true;
1674 }
1675 }
1676 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1677 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1678 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1679 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1680 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1681 mCurrentFrame.dropCount);
1682}
1683
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001684void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001685 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1687 for(int index = 0;index < nYuvCount; index++){
1688 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1689 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1690
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001691 if(mCurrentFrame.drop[nYuvIndex]) {
1692 continue;
1693 }
1694
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001695 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001696 if(!frame.isFBComposed[nYuvIndex]) {
1697 frame.isFBComposed[nYuvIndex] = true;
1698 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001699 }
1700 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001701 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001702 private_handle_t *hnd = (private_handle_t *)layer->handle;
1703 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001704 frame.isFBComposed[nYuvIndex] = false;
1705 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001706 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001707 }
1708 }
1709 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001710
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001711 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1712 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001713}
1714
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001715void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1716 hwc_display_contents_1_t* list) {
1717 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1718 for(int index = 0;index < nSecureRGBCount; index++){
1719 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1720 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1721
1722 if(!isSecureRGBDoable(ctx, layer)) {
1723 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1724 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1725 mCurrentFrame.fbCount++;
1726 }
1727 } else {
1728 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1729 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1730 mCurrentFrame.fbCount--;
1731 }
1732 }
1733 }
1734
1735 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1736 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1737 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1738 mCurrentFrame.fbCount);
1739}
1740
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001741hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1742 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001743 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001744
1745 /* Update only the region of FB needed for composition */
1746 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1747 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1748 hwc_layer_1_t* layer = &list->hwLayers[i];
1749 hwc_rect_t dst = layer->displayFrame;
1750 fbRect = getUnion(fbRect, dst);
1751 }
1752 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001753 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001754 return fbRect;
1755}
1756
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001757bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1758 hwc_display_contents_1_t* list) {
1759
1760 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001761 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001762 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1763 return false;
1764 }
1765
1766 //Limitations checks
1767 if(!hwLimitationsCheck(ctx, list)) {
1768 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1769 return false;
1770 }
1771
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001772 //Configure framebuffer first if applicable
1773 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001774 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001775 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1776 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001777 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1778 __FUNCTION__);
1779 return false;
1780 }
1781 }
1782
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001783 mCurrentFrame.map();
1784
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001785 if(!allocLayerPipes(ctx, list)) {
1786 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001787 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001788 }
1789
1790 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001791 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001792 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001793 int mdpIndex = mCurrentFrame.layerToMDP[index];
1794 hwc_layer_1_t* layer = &list->hwLayers[index];
1795
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301796 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1797 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1798 mdpNextZOrder++;
1799 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001800 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1801 cur_pipe->zOrder = mdpNextZOrder++;
1802
radhakrishnac9a67412013-09-25 17:40:42 +05301803 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301804 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301805 if(configure4k2kYuv(ctx, layer,
1806 mCurrentFrame.mdpToLayer[mdpIndex])
1807 != 0 ){
1808 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1809 for layer %d",__FUNCTION__, index);
1810 return false;
1811 }
1812 else{
1813 mdpNextZOrder++;
1814 }
1815 continue;
1816 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001817 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1818 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301819 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001820 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001821 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001822 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001823 }
1824
Saurabh Shaha36be922013-12-16 18:18:39 -08001825 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1826 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1827 ,__FUNCTION__, mDpy);
1828 return false;
1829 }
1830
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001831 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001832 return true;
1833}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001834
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001835bool MDPComp::resourceCheck(hwc_context_t* ctx,
1836 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001837 const bool fbUsed = mCurrentFrame.fbCount;
1838 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1839 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1840 return false;
1841 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001842
1843 //Will benefit cases where a video has non-updating background.
1844 if((mDpy > HWC_DISPLAY_PRIMARY) and
1845 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1846 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1847 return false;
1848 }
1849
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001850 // Init rotCount to number of rotate sessions used by other displays
1851 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1852 // Count the number of rotator sessions required for current display
1853 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1854 if(!mCurrentFrame.isFBComposed[index]) {
1855 hwc_layer_1_t* layer = &list->hwLayers[index];
1856 private_handle_t *hnd = (private_handle_t *)layer->handle;
1857 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1858 rotCount++;
1859 }
1860 }
1861 }
1862 // if number of layers to rotate exceeds max rotator sessions, bail out.
1863 if(rotCount > RotMgr::MAX_ROT_SESS) {
1864 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1865 __FUNCTION__, mDpy);
1866 return false;
1867 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001868 return true;
1869}
1870
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301871bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1872 hwc_display_contents_1_t* list) {
1873
1874 //A-family hw limitation:
1875 //If a layer need alpha scaling, MDP can not support.
1876 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1877 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1878 if(!mCurrentFrame.isFBComposed[i] &&
1879 isAlphaScaled( &list->hwLayers[i])) {
1880 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1881 return false;
1882 }
1883 }
1884 }
1885
1886 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1887 //If multiple layers requires downscaling and also they are overlapping
1888 //fall back to GPU since MDSS can not handle it.
1889 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1890 qdutils::MDPVersion::getInstance().is8x26()) {
1891 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1892 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1893 if(!mCurrentFrame.isFBComposed[i] &&
1894 isDownscaleRequired(botLayer)) {
1895 //if layer-i is marked for MDP and needs downscaling
1896 //check if any MDP layer on top of i & overlaps with layer-i
1897 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1898 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1899 if(!mCurrentFrame.isFBComposed[j] &&
1900 isDownscaleRequired(topLayer)) {
1901 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1902 topLayer->displayFrame);
1903 if(isValidRect(r))
1904 return false;
1905 }
1906 }
1907 }
1908 }
1909 }
1910 return true;
1911}
1912
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001913// Checks only if videos or single layer(RGB) is updating
1914// which is used for setting dynamic fps or perf hint for single
1915// layer video playback
1916bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1917 hwc_display_contents_1_t* list) {
1918 bool support = false;
1919 FrameInfo frame;
1920 frame.reset(mCurrentFrame.layerCount);
1921 memset(&frame.drop, 0, sizeof(frame.drop));
1922 frame.dropCount = 0;
1923 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1924 updateLayerCache(ctx, list, frame);
1925 updateYUV(ctx, list, false /*secure only*/, frame);
1926 // There are only updating YUV layers or there is single RGB
1927 // Layer(Youtube)
1928 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1929 (frame.layerCount == 1)) {
1930 support = true;
1931 }
1932 return support;
1933}
1934
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301935void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1936 //For primary display, set the dynamic refreshrate
1937 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1938 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301939 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1940 MDPVersion& mdpHw = MDPVersion::getInstance();
1941 if(sIdleFallBack) {
1942 //Set minimum panel refresh rate during idle timeout
1943 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001944 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301945 //Set the new fresh rate, if there is only one updating YUV layer
1946 //or there is one single RGB layer with this request
1947 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1948 }
1949 setRefreshRate(ctx, mDpy, refreshRate);
1950 }
1951}
1952
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001953int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001954 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001955 char property[PROPERTY_VALUE_MAX];
1956
Raj Kamal4393eaa2014-06-06 13:45:20 +05301957 if(!ctx || !list) {
1958 ALOGE("%s: Invalid context or list",__FUNCTION__);
1959 mCachedFrame.reset();
1960 return -1;
1961 }
1962
1963 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001964 if(mDpy == HWC_DISPLAY_PRIMARY) {
1965 sSimulationFlags = 0;
1966 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1967 int currentFlags = atoi(property);
1968 if(currentFlags != sSimulationFlags) {
1969 sSimulationFlags = currentFlags;
1970 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1971 sSimulationFlags, sSimulationFlags);
1972 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001973 }
1974 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001975 // reset PTOR
1976 if(!mDpy)
1977 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001978
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301979 //reset old data
1980 mCurrentFrame.reset(numLayers);
1981 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1982 mCurrentFrame.dropCount = 0;
1983
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301984 //Do not cache the information for next draw cycle.
1985 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1986 ALOGI("%s: Unsupported layer count for mdp composition",
1987 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001988 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301989#ifdef DYNAMIC_FPS
1990 setDynRefreshRate(ctx, list);
1991#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001992 return -1;
1993 }
1994
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001995 // Detect the start of animation and fall back to GPU only once to cache
1996 // all the layers in FB and display FB content untill animation completes.
1997 if(ctx->listStats[mDpy].isDisplayAnimating) {
1998 mCurrentFrame.needsRedraw = false;
1999 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2000 mCurrentFrame.needsRedraw = true;
2001 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2002 }
2003 setMDPCompLayerFlags(ctx, list);
2004 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302005#ifdef DYNAMIC_FPS
2006 setDynRefreshRate(ctx, list);
2007#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002008 ret = -1;
2009 return ret;
2010 } else {
2011 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2012 }
2013
Saurabh Shahb39f8152013-08-22 10:21:44 -07002014 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002015 if(isFrameDoable(ctx)) {
2016 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002017 // if AIV Video mode is enabled, drop all non AIV layers from the
2018 // external display list.
2019 if(ctx->listStats[mDpy].mAIVVideoMode) {
2020 dropNonAIVLayers(ctx, list);
2021 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002022
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002023 // if tryFullFrame fails, try to push all video and secure RGB layers
2024 // to MDP for composition.
2025 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002026 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302027 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002028 setMDPCompLayerFlags(ctx, list);
2029 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002030 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002031 reset(ctx);
2032 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2033 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002034 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002035 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2036 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002037 }
2038 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302039 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2040 enablePartialUpdateForMDP3) {
2041 generateROI(ctx, list);
2042 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2043 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2044 }
2045 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002046 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2047 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002048 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002049 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002050
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002051 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002052 ALOGD("GEOMETRY change: %d",
2053 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002054 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002055 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002056 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002057 }
2058
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002059#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302060 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002061#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002062 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002063
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002064 mCachedFrame.cacheAll(list);
2065 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002066 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002067}
2068
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002069bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302070
2071 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302072 int mdpIndex = mCurrentFrame.layerToMDP[index];
2073 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2074 info.pipeInfo = new MdpYUVPipeInfo;
2075 info.rot = NULL;
2076 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302077
2078 pipe_info.lIndex = ovutils::OV_INVALID;
2079 pipe_info.rIndex = ovutils::OV_INVALID;
2080
Saurabh Shahc62f3982014-03-05 14:28:26 -08002081 Overlay::PipeSpecs pipeSpecs;
2082 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2083 pipeSpecs.needsScaling = true;
2084 pipeSpecs.dpy = mDpy;
2085 pipeSpecs.fb = false;
2086
2087 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302088 if(pipe_info.lIndex == ovutils::OV_INVALID){
2089 bRet = false;
2090 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2091 __FUNCTION__);
2092 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002093 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302094 if(pipe_info.rIndex == ovutils::OV_INVALID){
2095 bRet = false;
2096 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2097 __FUNCTION__);
2098 }
2099 return bRet;
2100}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002101
2102int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2103 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002104 if (ctx->mPtorInfo.isActive()) {
2105 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002106 if (fd < 0) {
2107 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002108 }
2109 }
2110 return fd;
2111}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002112//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002113
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002114void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302115 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002116 //If 4k2k Yuv layer split is possible, and if
2117 //fbz is above 4k2k layer, increment fb zorder by 1
2118 //as we split 4k2k layer and increment zorder for right half
2119 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002120 if(!ctx)
2121 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002122 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302123 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2124 index++) {
2125 if(!mCurrentFrame.isFBComposed[index]) {
2126 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2127 mdpNextZOrder++;
2128 }
2129 mdpNextZOrder++;
2130 hwc_layer_1_t* layer = &list->hwLayers[index];
2131 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302132 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302133 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2134 mCurrentFrame.fbZ += 1;
2135 mdpNextZOrder++;
2136 //As we split 4kx2k yuv layer and program to 2 VG pipes
2137 //(if available) increase mdpcount by 1.
2138 mCurrentFrame.mdpCount++;
2139 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002140 }
2141 }
2142 }
radhakrishnac9a67412013-09-25 17:40:42 +05302143}
2144
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002145/*
2146 * Configures pipe(s) for MDP composition
2147 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002148int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002149 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002150 MdpPipeInfoNonSplit& mdp_info =
2151 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302152 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002153 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002154 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002155
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002156 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2157 __FUNCTION__, layer, zOrder, dest);
2158
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002159 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002160 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002161}
2162
Saurabh Shah88e4d272013-09-03 13:31:29 -07002163bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002164 hwc_display_contents_1_t* list) {
2165 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002166
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002167 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002168
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002169 hwc_layer_1_t* layer = &list->hwLayers[index];
2170 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302171 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002172 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302173 continue;
2174 }
2175 }
2176
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002177 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002178 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002179 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002180 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002181 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002182
Saurabh Shahc62f3982014-03-05 14:28:26 -08002183 Overlay::PipeSpecs pipeSpecs;
2184 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2185 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2186 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2187 (qdutils::MDPVersion::getInstance().is8x26() and
2188 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2189 pipeSpecs.dpy = mDpy;
2190 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002191 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002192
Saurabh Shahc62f3982014-03-05 14:28:26 -08002193 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2194
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002195 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002196 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002197 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002198 }
2199 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002200 return true;
2201}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002202
radhakrishnac9a67412013-09-25 17:40:42 +05302203int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2204 PipeLayerPair& PipeLayerPair) {
2205 MdpYUVPipeInfo& mdp_info =
2206 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2207 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302208 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302209 eDest lDest = mdp_info.lIndex;
2210 eDest rDest = mdp_info.rIndex;
2211
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002212 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302213 lDest, rDest, &PipeLayerPair.rot);
2214}
2215
Saurabh Shah88e4d272013-09-03 13:31:29 -07002216bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002217
Raj Kamal4393eaa2014-06-06 13:45:20 +05302218 if(!isEnabled() or !mModeOn) {
2219 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302220 return true;
2221 }
2222
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002223 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002224 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002225 sHandleTimeout = true;
2226 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002227
2228 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002229 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002230
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002231 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2232 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002233 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002234 if(mCurrentFrame.isFBComposed[i]) continue;
2235
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002236 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002237 private_handle_t *hnd = (private_handle_t *)layer->handle;
2238 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002239 if (!(layer->flags & HWC_COLOR_FILL)) {
2240 ALOGE("%s handle null", __FUNCTION__);
2241 return false;
2242 }
2243 // No PLAY for Color layer
2244 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2245 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002246 }
2247
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002248 int mdpIndex = mCurrentFrame.layerToMDP[i];
2249
Raj Kamal389d6e32014-08-04 14:43:24 +05302250 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302251 {
2252 MdpYUVPipeInfo& pipe_info =
2253 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2254 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2255 ovutils::eDest indexL = pipe_info.lIndex;
2256 ovutils::eDest indexR = pipe_info.rIndex;
2257 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302258 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302259 if(rot) {
2260 rot->queueBuffer(fd, offset);
2261 fd = rot->getDstMemId();
2262 offset = rot->getDstOffset();
2263 }
2264 if(indexL != ovutils::OV_INVALID) {
2265 ovutils::eDest destL = (ovutils::eDest)indexL;
2266 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2267 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2268 if (!ov.queueBuffer(fd, offset, destL)) {
2269 ALOGE("%s: queueBuffer failed for display:%d",
2270 __FUNCTION__, mDpy);
2271 return false;
2272 }
2273 }
2274
2275 if(indexR != ovutils::OV_INVALID) {
2276 ovutils::eDest destR = (ovutils::eDest)indexR;
2277 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2278 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2279 if (!ov.queueBuffer(fd, offset, destR)) {
2280 ALOGE("%s: queueBuffer failed for display:%d",
2281 __FUNCTION__, mDpy);
2282 return false;
2283 }
2284 }
2285 }
2286 else{
2287 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002288 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302289 ovutils::eDest dest = pipe_info.index;
2290 if(dest == ovutils::OV_INVALID) {
2291 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002292 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302293 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002294
radhakrishnac9a67412013-09-25 17:40:42 +05302295 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2296 continue;
2297 }
2298
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002299 int fd = hnd->fd;
2300 uint32_t offset = (uint32_t)hnd->offset;
2301 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2302 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002303 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002304 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002305 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002306 }
2307
radhakrishnac9a67412013-09-25 17:40:42 +05302308 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2309 using pipe: %d", __FUNCTION__, layer,
2310 hnd, dest );
2311
radhakrishnac9a67412013-09-25 17:40:42 +05302312 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2313 if(rot) {
2314 if(!rot->queueBuffer(fd, offset))
2315 return false;
2316 fd = rot->getDstMemId();
2317 offset = rot->getDstOffset();
2318 }
2319
2320 if (!ov.queueBuffer(fd, offset, dest)) {
2321 ALOGE("%s: queueBuffer failed for display:%d ",
2322 __FUNCTION__, mDpy);
2323 return false;
2324 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002325 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002326
2327 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002328 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002329 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002330}
2331
Saurabh Shah88e4d272013-09-03 13:31:29 -07002332//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002333
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002334void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302335 hwc_display_contents_1_t* list){
2336 //if 4kx2k yuv layer is totally present in either in left half
2337 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302338 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302339 if(mCurrentFrame.fbZ >= 0) {
2340 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2341 index++) {
2342 if(!mCurrentFrame.isFBComposed[index]) {
2343 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2344 mdpNextZOrder++;
2345 }
2346 mdpNextZOrder++;
2347 hwc_layer_1_t* layer = &list->hwLayers[index];
2348 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302349 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302350 hwc_rect_t dst = layer->displayFrame;
2351 if((dst.left > lSplit) || (dst.right < lSplit)) {
2352 mCurrentFrame.mdpCount += 1;
2353 }
2354 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2355 mCurrentFrame.fbZ += 1;
2356 mdpNextZOrder++;
2357 }
2358 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002359 }
radhakrishnac9a67412013-09-25 17:40:42 +05302360 }
2361}
2362
Saurabh Shah88e4d272013-09-03 13:31:29 -07002363bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002364 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002365
Saurabh Shahc62f3982014-03-05 14:28:26 -08002366 const int lSplit = getLeftSplit(ctx, mDpy);
2367 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002368 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002369 pipe_info.lIndex = ovutils::OV_INVALID;
2370 pipe_info.rIndex = ovutils::OV_INVALID;
2371
Saurabh Shahc62f3982014-03-05 14:28:26 -08002372 Overlay::PipeSpecs pipeSpecs;
2373 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2374 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2375 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2376 pipeSpecs.dpy = mDpy;
2377 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2378 pipeSpecs.fb = false;
2379
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002380 // Acquire pipe only for the updating half
2381 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2382 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2383
2384 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002385 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002386 if(pipe_info.lIndex == ovutils::OV_INVALID)
2387 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002388 }
2389
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002390 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002391 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2392 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002393 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002394 return false;
2395 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002396
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002397 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002398}
2399
Saurabh Shah88e4d272013-09-03 13:31:29 -07002400bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002401 hwc_display_contents_1_t* list) {
2402 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002404 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002405
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002406 hwc_layer_1_t* layer = &list->hwLayers[index];
2407 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302408 hwc_rect_t dst = layer->displayFrame;
2409 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302410 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302411 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002412 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302413 continue;
2414 }
2415 }
2416 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002417 int mdpIndex = mCurrentFrame.layerToMDP[index];
2418 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002419 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002420 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002421 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002422
Saurabh Shahc62f3982014-03-05 14:28:26 -08002423 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2424 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2425 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002426 return false;
2427 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002428 }
2429 return true;
2430}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002431
radhakrishnac9a67412013-09-25 17:40:42 +05302432int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2433 PipeLayerPair& PipeLayerPair) {
2434 const int lSplit = getLeftSplit(ctx, mDpy);
2435 hwc_rect_t dst = layer->displayFrame;
2436 if((dst.left > lSplit)||(dst.right < lSplit)){
2437 MdpYUVPipeInfo& mdp_info =
2438 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2439 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302440 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302441 eDest lDest = mdp_info.lIndex;
2442 eDest rDest = mdp_info.rIndex;
2443
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002444 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302445 lDest, rDest, &PipeLayerPair.rot);
2446 }
2447 else{
2448 return configure(ctx, layer, PipeLayerPair);
2449 }
2450}
2451
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002452/*
2453 * Configures pipe(s) for MDP composition
2454 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002455int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002456 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002457 MdpPipeInfoSplit& mdp_info =
2458 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002459 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302460 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002461 eDest lDest = mdp_info.lIndex;
2462 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002463
2464 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002465 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002466
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002467 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002468 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002469}
2470
Saurabh Shah88e4d272013-09-03 13:31:29 -07002471bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002472
Raj Kamal4393eaa2014-06-06 13:45:20 +05302473 if(!isEnabled() or !mModeOn) {
2474 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302475 return true;
2476 }
2477
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002478 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002479 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002480 sHandleTimeout = true;
2481 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002482
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002483 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002484 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002485
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002486 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2487 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002488 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002489 if(mCurrentFrame.isFBComposed[i]) continue;
2490
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002491 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002492 private_handle_t *hnd = (private_handle_t *)layer->handle;
2493 if(!hnd) {
2494 ALOGE("%s handle null", __FUNCTION__);
2495 return false;
2496 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002497
2498 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2499 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002500 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002501
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002502 int mdpIndex = mCurrentFrame.layerToMDP[i];
2503
Raj Kamal389d6e32014-08-04 14:43:24 +05302504 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302505 {
2506 MdpYUVPipeInfo& pipe_info =
2507 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2508 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2509 ovutils::eDest indexL = pipe_info.lIndex;
2510 ovutils::eDest indexR = pipe_info.rIndex;
2511 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302512 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302513 if(rot) {
2514 rot->queueBuffer(fd, offset);
2515 fd = rot->getDstMemId();
2516 offset = rot->getDstOffset();
2517 }
2518 if(indexL != ovutils::OV_INVALID) {
2519 ovutils::eDest destL = (ovutils::eDest)indexL;
2520 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2521 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2522 if (!ov.queueBuffer(fd, offset, destL)) {
2523 ALOGE("%s: queueBuffer failed for display:%d",
2524 __FUNCTION__, mDpy);
2525 return false;
2526 }
2527 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002528
radhakrishnac9a67412013-09-25 17:40:42 +05302529 if(indexR != ovutils::OV_INVALID) {
2530 ovutils::eDest destR = (ovutils::eDest)indexR;
2531 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2532 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2533 if (!ov.queueBuffer(fd, offset, destR)) {
2534 ALOGE("%s: queueBuffer failed for display:%d",
2535 __FUNCTION__, mDpy);
2536 return false;
2537 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002538 }
2539 }
radhakrishnac9a67412013-09-25 17:40:42 +05302540 else{
2541 MdpPipeInfoSplit& pipe_info =
2542 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2543 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002544
radhakrishnac9a67412013-09-25 17:40:42 +05302545 ovutils::eDest indexL = pipe_info.lIndex;
2546 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002547
radhakrishnac9a67412013-09-25 17:40:42 +05302548 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002549 uint32_t offset = (uint32_t)hnd->offset;
2550 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2551 if (!mDpy && (index != -1)) {
2552 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2553 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002554 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002555 }
radhakrishnac9a67412013-09-25 17:40:42 +05302556
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002557 if(ctx->mAD->draw(ctx, fd, offset)) {
2558 fd = ctx->mAD->getDstFd();
2559 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002560 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002561
radhakrishnac9a67412013-09-25 17:40:42 +05302562 if(rot) {
2563 rot->queueBuffer(fd, offset);
2564 fd = rot->getDstMemId();
2565 offset = rot->getDstOffset();
2566 }
2567
2568 //************* play left mixer **********
2569 if(indexL != ovutils::OV_INVALID) {
2570 ovutils::eDest destL = (ovutils::eDest)indexL;
2571 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2572 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2573 if (!ov.queueBuffer(fd, offset, destL)) {
2574 ALOGE("%s: queueBuffer failed for left mixer",
2575 __FUNCTION__);
2576 return false;
2577 }
2578 }
2579
2580 //************* play right mixer **********
2581 if(indexR != ovutils::OV_INVALID) {
2582 ovutils::eDest destR = (ovutils::eDest)indexR;
2583 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2584 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2585 if (!ov.queueBuffer(fd, offset, destR)) {
2586 ALOGE("%s: queueBuffer failed for right mixer",
2587 __FUNCTION__);
2588 return false;
2589 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002590 }
2591 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002592
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002593 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2594 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002595
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002596 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002597}
Saurabh Shahab47c692014-02-12 18:45:57 -08002598
2599//================MDPCompSrcSplit==============================================
2600bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002601 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002602 private_handle_t *hnd = (private_handle_t *)layer->handle;
2603 hwc_rect_t dst = layer->displayFrame;
2604 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2605 pipe_info.lIndex = ovutils::OV_INVALID;
2606 pipe_info.rIndex = ovutils::OV_INVALID;
2607
2608 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2609 //should have a higher priority than the right one. Pipe priorities are
2610 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002611
Saurabh Shahc62f3982014-03-05 14:28:26 -08002612 Overlay::PipeSpecs pipeSpecs;
2613 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2614 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2615 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2616 pipeSpecs.dpy = mDpy;
2617 pipeSpecs.fb = false;
2618
Saurabh Shahab47c692014-02-12 18:45:57 -08002619 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002620 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002621 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002622 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002623 }
2624
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002625 /* Use 2 pipes IF
2626 a) Layer's crop width is > 2048 or
2627 b) Layer's dest width > 2048 or
2628 c) On primary, driver has indicated with caps to split always. This is
2629 based on an empirically derived value of panel height. Applied only
2630 if the layer's width is > mixer's width
2631 */
2632
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302633 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002634 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302635 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002636 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2637 const uint32_t dstWidth = dst.right - dst.left;
2638 const uint32_t dstHeight = dst.bottom - dst.top;
2639 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002640 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002641 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2642 crop.bottom - crop.top;
2643 //Approximation to actual clock, ignoring the common factors in pipe and
2644 //mixer cases like line_time
2645 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2646 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002647
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002648 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2649 //pipe line length, we are still using 2 pipes. This is fine just because
2650 //this is source split where destination doesn't matter. Evaluate later to
2651 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002652 if(dstWidth > mdpHw.getMaxPipeWidth() or
2653 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002654 (primarySplitAlways and
2655 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002656 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002657 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002658 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002659 }
2660
2661 // Return values
2662 // 1 Left pipe is higher priority, do nothing.
2663 // 0 Pipes of same priority.
2664 //-1 Right pipe is of higher priority, needs swap.
2665 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2666 pipe_info.rIndex) == -1) {
2667 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668 }
2669 }
2670
2671 return true;
2672}
2673
Saurabh Shahab47c692014-02-12 18:45:57 -08002674int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2675 PipeLayerPair& PipeLayerPair) {
2676 private_handle_t *hnd = (private_handle_t *)layer->handle;
2677 if(!hnd) {
2678 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2679 return -1;
2680 }
2681 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2682 MdpPipeInfoSplit& mdp_info =
2683 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2684 Rotator **rot = &PipeLayerPair.rot;
2685 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002686 eDest lDest = mdp_info.lIndex;
2687 eDest rDest = mdp_info.rIndex;
2688 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2689 hwc_rect_t dst = layer->displayFrame;
2690 int transform = layer->transform;
2691 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002692 int rotFlags = ROT_FLAGS_NONE;
2693 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2694 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2695
2696 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2697 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2698
2699 // Handle R/B swap
2700 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2701 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2702 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2703 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2704 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2705 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002706 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002707 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2708 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002709 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002710 /* Calculate the external display position based on MDP downscale,
2711 ActionSafe, and extorientation features. */
2712 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002713
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002714 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302715 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002716 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002717
2718 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2719 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002720 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002721 }
2722
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002723 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002724 (*rot) = ctx->mRotMgr->getNext();
2725 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002726 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002727 //If the video is using a single pipe, enable BWC
2728 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002729 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2730 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002731 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002732 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002733 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002734 ALOGE("%s: configRotator failed!", __FUNCTION__);
2735 return -1;
2736 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002737 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002738 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002739 }
2740
2741 //If 2 pipes being used, divide layer into half, crop and dst
2742 hwc_rect_t cropL = crop;
2743 hwc_rect_t cropR = crop;
2744 hwc_rect_t dstL = dst;
2745 hwc_rect_t dstR = dst;
2746 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2747 cropL.right = (crop.right + crop.left) / 2;
2748 cropR.left = cropL.right;
2749 sanitizeSourceCrop(cropL, cropR, hnd);
2750
Saurabh Shahb729b192014-08-15 18:04:24 -07002751 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002752 //Swap crops on H flip since 2 pipes are being used
2753 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2754 hwc_rect_t tmp = cropL;
2755 cropL = cropR;
2756 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002757 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002758 }
2759
Saurabh Shahb729b192014-08-15 18:04:24 -07002760 //cropSwap trick: If the src and dst widths are both odd, let us say
2761 //2507, then splitting both into half would cause left width to be 1253
2762 //and right 1254. If crop is swapped because of H flip, this will cause
2763 //left crop width to be 1254, whereas left dst width remains 1253, thus
2764 //inducing a scaling that is unaccounted for. To overcome that we add 1
2765 //to the dst width if there is a cropSwap. So if the original width was
2766 //2507, the left dst width will be 1254. Even if the original width was
2767 //even for ex: 2508, the left dst width will still remain 1254.
2768 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002769 dstR.left = dstL.right;
2770 }
2771
2772 //For the mdp, since either we are pre-rotating or MDP does flips
2773 orient = OVERLAY_TRANSFORM_0;
2774 transform = 0;
2775
2776 //configure left pipe
2777 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002778 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002779 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2780 (ovutils::eBlending) getBlending(layer->blending));
2781
2782 if(configMdp(ctx->mOverlay, pargL, orient,
2783 cropL, dstL, metadata, lDest) < 0) {
2784 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2785 return -1;
2786 }
2787 }
2788
2789 //configure right pipe
2790 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002791 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002792 static_cast<eRotFlags>(rotFlags),
2793 layer->planeAlpha,
2794 (ovutils::eBlending) getBlending(layer->blending));
2795 if(configMdp(ctx->mOverlay, pargR, orient,
2796 cropR, dstR, metadata, rDest) < 0) {
2797 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2798 return -1;
2799 }
2800 }
2801
2802 return 0;
2803}
2804
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002805bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2806 Locker::Autolock _l(ctx->mDrawLock);
2807 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2808 char path[MAX_SYSFS_FILE_PATH];
2809 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2810 int fd = open(path, O_RDONLY);
2811 if(fd < 0) {
2812 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2813 return -1;
2814 }
2815 char value[4];
2816 ssize_t size_read = read(fd, value, sizeof(value)-1);
2817 if(size_read <= 0) {
2818 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2819 close(fd);
2820 return -1;
2821 }
2822 close(fd);
2823 value[size_read] = '\0';
2824 return atoi(value);
2825}
2826
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002827int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2828 Locker::Autolock _l(ctx->mDrawLock);
2829 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2830 char path[MAX_SYSFS_FILE_PATH];
2831 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2832 int fd = open(path, O_WRONLY);
2833 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002834 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002835 return -1;
2836 }
2837 char value[4];
2838 snprintf(value, sizeof(value), "%d", (int)enable);
2839 ssize_t ret = write(fd, value, strlen(value));
2840 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002841 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002842 close(fd);
2843 return -1;
2844 }
2845 close(fd);
2846 sIsPartialUpdateActive = enable;
2847 return 0;
2848}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002849
2850bool MDPComp::loadPerfLib() {
2851 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2852 bool success = false;
2853 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2854 ALOGE("vendor library not set in ro.vendor.extension_library");
2855 return false;
2856 }
2857
2858 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
2859 if(sLibPerfHint) {
2860 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
2861 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
2862 if (!sPerfLockAcquire || !sPerfLockRelease) {
2863 ALOGE("Failed to load symbols for perfLock");
2864 dlclose(sLibPerfHint);
2865 sLibPerfHint = NULL;
2866 return false;
2867 }
2868 success = true;
2869 ALOGI("Successfully Loaded perf hint API's");
2870 } else {
2871 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
2872 }
2873 return success;
2874}
2875
2876void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2877 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
2878 return;
2879 }
2880 static int count = sPerfHintWindow;
2881 static int perflockFlag = 0;
2882
2883 /* Send hint to mpctl when single layer is updated
2884 * for a successful number of windows. Hint release
2885 * happens immediately upon multiple layer update.
2886 */
2887 if (onlyVideosUpdating(ctx, list)) {
2888 if(count) {
2889 count--;
2890 }
2891 } else {
2892 if (perflockFlag) {
2893 perflockFlag = 0;
2894 sPerfLockRelease(sPerfLockHandle);
2895 }
2896 count = sPerfHintWindow;
2897 }
2898 if (count == 0 && !perflockFlag) {
2899 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
2900 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
2901 &perfHint, sizeof(perfHint)/sizeof(int));
2902 if(sPerfLockHandle < 0) {
2903 ALOGE("Perf Lock Acquire Failed");
2904 } else {
2905 perflockFlag = 1;
2906 }
2907 }
2908}
2909
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002910}; //namespace
2911