blob: cdb539628a9bc67bfdc3118fd47ecddcca0e4f05 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080022#include <dlfcn.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070023#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070030#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080031
Saurabh Shah85234ec2013-04-12 17:09:00 -070032using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070033using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080034using namespace overlay::utils;
35namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037namespace qhwc {
38
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080039//==============MDPComp========================================================
40
Saurabh Shah59562ff2014-09-30 16:13:12 -070041IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080043bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070044bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050045bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070046bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070047int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070048int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053049bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070050bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080051int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053052bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070053bool MDPComp::sIsPartialUpdateActive = true;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080054void *MDPComp::sLibPerfHint = NULL;
55int MDPComp::sPerfLockHandle = 0;
56int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
57int (*MDPComp::sPerfLockRelease)(int value) = NULL;
58int MDPComp::sPerfHintWindow = -1;
59
Saurabh Shah88e4d272013-09-03 13:31:29 -070060MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070061 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
62 sSrcSplitEnabled = true;
63 return new MDPCompSrcSplit(dpy);
64 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070065 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080066 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070067 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080068}
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070MDPComp::MDPComp(int dpy):mDpy(dpy){};
71
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070072void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080073{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070074 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
75 return;
76
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080077 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070078 (mDpy == 0) ? "\"PRIMARY\"" :
79 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070080 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
81 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080082 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
83 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
84 (mCurrentFrame.needsRedraw? "YES" : "NO"),
85 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070086 if(isDisplaySplit(ctx, mDpy)) {
87 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
88 "Right: [%d, %d, %d, %d] \n",
89 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
90 ctx->listStats[mDpy].lRoi.right,
91 ctx->listStats[mDpy].lRoi.bottom,
92 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
93 ctx->listStats[mDpy].rRoi.right,
94 ctx->listStats[mDpy].rRoi.bottom);
95 } else {
96 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
97 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
98 ctx->listStats[mDpy].lRoi.right,
99 ctx->listStats[mDpy].lRoi.bottom);
100 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 dumpsys_log(buf," --------------------------------------------- \n");
102 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
103 dumpsys_log(buf," --------------------------------------------- \n");
104 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
105 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
106 index,
107 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700108 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800109 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700110 (mCurrentFrame.drop[index] ? "DROP" :
111 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800112 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
113 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
114 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115}
116
117bool MDPComp::init(hwc_context_t *ctx) {
118
119 if(!ctx) {
120 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
121 return false;
122 }
123
Saurabh Shah59562ff2014-09-30 16:13:12 -0700124 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800125
126 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530127 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
128 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800131 sEnabled = true;
132 }
133
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700134 sEnableMixedMode = true;
135 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
136 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
137 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
138 sEnableMixedMode = false;
139 }
140
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700141 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
142
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800143 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700144 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700145 int val = atoi(property);
146 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700147 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800148 }
149
Saurabh Shahacec8e42014-11-25 11:07:04 -0800150 /* Maximum layers allowed to use MDP on secondary panels. If property
151 * doesn't exist, default to 1. Using the property it can be set to 0 or
152 * more.
153 */
154 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
155 int val = atoi(property);
156 sMaxSecLayers = (val >= 0) ? val : 1;
157 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
158 }
159
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700161 sIdleInvalidator = IdleInvalidator::getInstance();
162 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
163 delete sIdleInvalidator;
164 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400165 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800166 }
radhakrishnac9a67412013-09-25 17:40:42 +0530167
Saurabh Shah7c727642014-06-02 15:47:14 -0700168 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700169 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700170 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
171 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
172 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530173 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530174 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700175
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530176 bool defaultPTOR = false;
177 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
178 //8x16 and 8x39 targets by default
179 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
180 (qdutils::MDPVersion::getInstance().is8x16() ||
181 qdutils::MDPVersion::getInstance().is8x39())) {
182 defaultPTOR = true;
183 }
184
185 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
186 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700187 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
188 HWC_DISPLAY_PRIMARY);
189 }
190
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530191 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
192 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
193 enablePartialUpdateForMDP3 = true;
194 }
195
196 if(!enablePartialUpdateForMDP3 &&
197 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
198 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
199 enablePartialUpdateForMDP3 = true;
200 }
201
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800202 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
203
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800204 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
205 int val = atoi(property);
206 if(val > 0 && loadPerfLib()) {
207 sPerfHintWindow = val;
208 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
209 }
210 }
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212 return true;
213}
214
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800215void MDPComp::reset(hwc_context_t *ctx) {
216 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700217 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800218 ctx->mOverlay->clear(mDpy);
219 ctx->mLayerRotMap[mDpy]->clear();
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))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530393 (not isValidDimension(ctx,layer)) ||
394 isSkipLayer(layer)) {
395 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700396 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
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700785 // if secondary is configuring or Padding round, fall back to video only
786 // composition and release all assigned non VIG pipes from primary.
787 if(isSecondaryConfiguring(ctx)) {
788 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
789 __FUNCTION__);
790 return false;
791 } else if(ctx->isPaddingRound) {
792 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
793 __FUNCTION__,mDpy);
794 return false;
795 }
796
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700797 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800798 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700799 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800800 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
801 return false;
802 }
803
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800804 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800805 hwc_layer_1_t* layer = &list->hwLayers[i];
806 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800807
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800808 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700809 if(!canUseRotator(ctx, mDpy)) {
810 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
811 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700812 return false;
813 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800814 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530815
816 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
817 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800818 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700819 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530820 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
821 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
822 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800823 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700824
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700825 if(ctx->mAD->isDoable()) {
826 return false;
827 }
828
Saurabh Shahaa236822013-04-24 18:07:26 -0700829 //If all above hard conditions are met we can do full or partial MDP comp.
830 bool ret = false;
831 if(fullMDPComp(ctx, list)) {
832 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700833 } else if(fullMDPCompWithPTOR(ctx, list)) {
834 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700835 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700836 ret = true;
837 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530838
Saurabh Shahaa236822013-04-24 18:07:26 -0700839 return ret;
840}
841
842bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700843
844 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
845 return false;
846
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700847 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
848 for(int i = 0; i < numAppLayers; i++) {
849 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700850 if(not mCurrentFrame.drop[i] and
851 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700852 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
853 return false;
854 }
855 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800856
Saurabh Shahaa236822013-04-24 18:07:26 -0700857 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700858 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
859 sizeof(mCurrentFrame.isFBComposed));
860 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
861 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700862
Raj Kamal389d6e32014-08-04 14:43:24 +0530863 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800864 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530865 }
866
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800867 if(!postHeuristicsHandling(ctx, list)) {
868 ALOGD_IF(isDebug(), "post heuristic handling failed");
869 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700870 return false;
871 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700872 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
873 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700874 return true;
875}
876
Sushil Chauhandefd3522014-05-13 18:17:12 -0700877/* Full MDP Composition with Peripheral Tiny Overlap Removal.
878 * MDP bandwidth limitations can be avoided, if the overlap region
879 * covered by the smallest layer at a higher z-order, gets composed
880 * by Copybit on a render buffer, which can be queued to MDP.
881 */
882bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
883 hwc_display_contents_1_t* list) {
884
885 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
886 const int stagesForMDP = min(sMaxPipesPerMixer,
887 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
888
889 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700890 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700891 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
892 return false;
893 }
894
895 // Frame level checks
896 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
897 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
898 isSecurePresent(ctx, mDpy)) {
899 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
900 return false;
901 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700902 // MDP comp checks
903 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700904 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700905 if(not isSupportedForMDPComp(ctx, layer)) {
906 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
907 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700908 }
909 }
910
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 /* We cannot use this composition mode, if:
912 1. A below layer needs scaling.
913 2. Overlap is not peripheral to display.
914 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700915 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700916 */
917
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
919 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
920 memset(overlapRect, 0, sizeof(overlapRect));
921 int layerPixelCount, minPixelCount = 0;
922 int numPTORLayersFound = 0;
923 for (int i = numAppLayers-1; (i >= 0 &&
924 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700925 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700926 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700927 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700928 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
929 // PTOR layer should be peripheral and cannot have transform
930 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
931 has90Transform(layer)) {
932 continue;
933 }
934 if((3 * (layerPixelCount + minPixelCount)) >
935 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
936 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
937 continue;
938 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700939 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700940 for (int j = i-1; j >= 0; j--) {
941 // Check if the layers below this layer qualifies for PTOR comp
942 hwc_layer_1_t* layer = &list->hwLayers[j];
943 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700944 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700945 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700946 if (isValidRect(getIntersection(dispFrame, disFrame))) {
947 if (has90Transform(layer) || needsScaling(layer)) {
948 found = false;
949 break;
950 }
951 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700952 }
953 }
954 // Store the minLayer Index
955 if(found) {
956 minLayerIndex[numPTORLayersFound] = i;
957 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
958 minPixelCount += layerPixelCount;
959 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700960 }
961 }
962
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700963 // No overlap layers
964 if (!numPTORLayersFound)
965 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700966
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700967 // Store the displayFrame and the sourceCrops of the layers
968 hwc_rect_t displayFrame[numAppLayers];
969 hwc_rect_t sourceCrop[numAppLayers];
970 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700971 hwc_layer_1_t* layer = &list->hwLayers[i];
972 displayFrame[i] = layer->displayFrame;
973 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700974 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700975
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530976 /**
977 * It's possible that 2 PTOR layers might have overlapping.
978 * In such case, remove the intersection(again if peripheral)
979 * from the lower PTOR layer to avoid overlapping.
980 * If intersection is not on peripheral then compromise
981 * by reducing number of PTOR layers.
982 **/
983 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
984 if(isValidRect(commonRect)) {
985 overlapRect[1] = deductRect(overlapRect[1], commonRect);
986 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
987 }
988
989 ctx->mPtorInfo.count = numPTORLayersFound;
990 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
991 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
992 }
993
994 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
995 // reset PTOR
996 ctx->mPtorInfo.count = 0;
997 if(isValidRect(commonRect)) {
998 // If PTORs are intersecting restore displayframe of PTOR[1]
999 // before returning, as we have modified it above.
1000 list->hwLayers[minLayerIndex[1]].displayFrame =
1001 displayFrame[minLayerIndex[1]];
1002 }
1003 return false;
1004 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001005 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1006 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1007
Xu Yangcda012c2014-07-30 21:57:21 +08001008 // Store the blending mode, planeAlpha, and transform of PTOR layers
1009 int32_t blending[numPTORLayersFound];
1010 uint8_t planeAlpha[numPTORLayersFound];
1011 uint32_t transform[numPTORLayersFound];
1012
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001013 for(int j = 0; j < numPTORLayersFound; j++) {
1014 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001015
1016 // Update src crop of PTOR layer
1017 hwc_layer_1_t* layer = &list->hwLayers[index];
1018 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1019 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1020 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1021 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1022
1023 // Store & update w, h, format of PTOR layer
1024 private_handle_t *hnd = (private_handle_t *)layer->handle;
1025 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1026 layerWhf[j] = whf;
1027 hnd->width = renderBuf->width;
1028 hnd->height = renderBuf->height;
1029 hnd->format = renderBuf->format;
1030
Xu Yangcda012c2014-07-30 21:57:21 +08001031 // Store & update blending mode, planeAlpha and transform of PTOR layer
1032 blending[j] = layer->blending;
1033 planeAlpha[j] = layer->planeAlpha;
1034 transform[j] = layer->transform;
1035 layer->blending = HWC_BLENDING_NONE;
1036 layer->planeAlpha = 0xFF;
1037 layer->transform = 0;
1038
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001039 // Remove overlap from crop & displayFrame of below layers
1040 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001041 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001042 if(!isValidRect(getIntersection(layer->displayFrame,
1043 overlapRect[j]))) {
1044 continue;
1045 }
1046 // Update layer attributes
1047 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1048 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301049 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001050 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1051 layer->transform);
1052 layer->sourceCropf.left = (float)srcCrop.left;
1053 layer->sourceCropf.top = (float)srcCrop.top;
1054 layer->sourceCropf.right = (float)srcCrop.right;
1055 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1056 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001057 }
1058
1059 mCurrentFrame.mdpCount = numAppLayers;
1060 mCurrentFrame.fbCount = 0;
1061 mCurrentFrame.fbZ = -1;
1062
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301063 for (int j = 0; j < numAppLayers; j++) {
1064 if(isValidRect(list->hwLayers[j].displayFrame)) {
1065 mCurrentFrame.isFBComposed[j] = false;
1066 } else {
1067 mCurrentFrame.mdpCount--;
1068 mCurrentFrame.drop[j] = true;
1069 }
1070 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001071
1072 bool result = postHeuristicsHandling(ctx, list);
1073
1074 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001075 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001076 hwc_layer_1_t* layer = &list->hwLayers[i];
1077 layer->displayFrame = displayFrame[i];
1078 layer->sourceCropf.left = (float)sourceCrop[i].left;
1079 layer->sourceCropf.top = (float)sourceCrop[i].top;
1080 layer->sourceCropf.right = (float)sourceCrop[i].right;
1081 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1082 }
1083
Xu Yangcda012c2014-07-30 21:57:21 +08001084 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001085 for (int i = 0; i < numPTORLayersFound; i++) {
1086 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001087 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001088 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1089 hnd->width = layerWhf[i].w;
1090 hnd->height = layerWhf[i].h;
1091 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001092 layer->blending = blending[i];
1093 layer->planeAlpha = planeAlpha[i];
1094 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001095 }
1096
Sushil Chauhandefd3522014-05-13 18:17:12 -07001097 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001098 // reset PTOR
1099 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001100 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001101 } else {
1102 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1103 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001104 }
1105
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001106 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1107 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001108 return result;
1109}
1110
Saurabh Shahaa236822013-04-24 18:07:26 -07001111bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1112{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001113 if(!sEnableMixedMode) {
1114 //Mixed mode is disabled. No need to even try caching.
1115 return false;
1116 }
1117
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001118 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301119 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1120 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001121 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001122 cacheBasedComp(ctx, list);
1123 } else {
1124 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001125 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001126 }
1127
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001128 return ret;
1129}
1130
1131bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1132 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001133 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1134 return false;
1135
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001136 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001137 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001138 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001139
1140 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1141 for(int i = 0; i < numAppLayers; i++) {
1142 if(!mCurrentFrame.isFBComposed[i]) {
1143 hwc_layer_1_t* layer = &list->hwLayers[i];
1144 if(not isSupportedForMDPComp(ctx, layer)) {
1145 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1146 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001147 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001148 return false;
1149 }
1150 }
1151 }
1152
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001153 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001154 /* mark secure RGB layers for MDP comp */
1155 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301156 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001157 if(!ret) {
1158 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001159 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001160 return false;
1161 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001162
1163 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001164
Raj Kamal389d6e32014-08-04 14:43:24 +05301165 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001166 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301167 }
1168
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001169 if(!postHeuristicsHandling(ctx, list)) {
1170 ALOGD_IF(isDebug(), "post heuristic handling failed");
1171 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001172 return false;
1173 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001174 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1175 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001176
Saurabh Shahaa236822013-04-24 18:07:26 -07001177 return true;
1178}
1179
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001180bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001181 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001182 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1183 return false;
1184
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001185 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001186 return false;
1187 }
1188
Saurabh Shahb772ae32013-11-18 15:40:02 -08001189 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001190 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1191 const int stagesForMDP = min(sMaxPipesPerMixer,
1192 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001193
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001194 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1195 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1196 int lastMDPSupportedIndex = numAppLayers;
1197 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001198
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001199 //Find the minimum MDP batch size
1200 for(int i = 0; i < numAppLayers;i++) {
1201 if(mCurrentFrame.drop[i]) {
1202 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001203 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001204 }
1205 hwc_layer_1_t* layer = &list->hwLayers[i];
1206 if(not isSupportedForMDPComp(ctx, layer)) {
1207 lastMDPSupportedIndex = i;
1208 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1209 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001210 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001211 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001212 }
1213
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001214 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1215 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1216 mCurrentFrame.dropCount);
1217
1218 //Start at a point where the fb batch should at least have 2 layers, for
1219 //this mode to be justified.
1220 while(fbBatchSize < 2) {
1221 ++fbBatchSize;
1222 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001223 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001224
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001225 //If there are no layers for MDP, this mode doesnt make sense.
1226 if(mdpBatchSize < 1) {
1227 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1228 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001229 return false;
1230 }
1231
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001232 mCurrentFrame.reset(numAppLayers);
1233
1234 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1235 while(mdpBatchSize > 0) {
1236 //Mark layers for MDP comp
1237 int mdpBatchLeft = mdpBatchSize;
1238 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1239 if(mCurrentFrame.drop[i]) {
1240 continue;
1241 }
1242 mCurrentFrame.isFBComposed[i] = false;
1243 --mdpBatchLeft;
1244 }
1245
1246 mCurrentFrame.fbZ = mdpBatchSize;
1247 mCurrentFrame.fbCount = fbBatchSize;
1248 mCurrentFrame.mdpCount = mdpBatchSize;
1249
1250 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1251 __FUNCTION__, mdpBatchSize, fbBatchSize,
1252 mCurrentFrame.dropCount);
1253
1254 if(postHeuristicsHandling(ctx, list)) {
1255 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001256 __FUNCTION__);
1257 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1258 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001259 return true;
1260 }
1261
1262 reset(ctx);
1263 --mdpBatchSize;
1264 ++fbBatchSize;
1265 }
1266
1267 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001268}
1269
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001270bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301271 if(mDpy or isSecurePresent(ctx, mDpy) or
1272 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001273 return false;
1274 }
1275 return true;
1276}
1277
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001278bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1279 hwc_display_contents_1_t* list){
1280 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1281 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001282 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001283 return false;
1284 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001285 if(ctx->listStats[mDpy].secureUI)
1286 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001287 return true;
1288}
1289
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001290bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1291 hwc_display_contents_1_t* list) {
1292 const bool secureOnly = true;
1293 return videoOnlyComp(ctx, list, not secureOnly) or
1294 videoOnlyComp(ctx, list, secureOnly);
1295}
1296
1297bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001298 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001299 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1300 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301301
Saurabh Shahaa236822013-04-24 18:07:26 -07001302 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301303 if(!isSecurePresent(ctx, mDpy)) {
1304 /* Bail out if we are processing only secured video layers
1305 * and we dont have any */
1306 if(secureOnly) {
1307 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1308 return false;
1309 }
1310 /* No Idle fall back for secure video layers and if there is only
1311 * single layer being composed. */
1312 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1313 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1314 return false;
1315 }
1316 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001317
Saurabh Shahaa236822013-04-24 18:07:26 -07001318 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001319 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001320 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001321 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001322
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001323 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1324 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001325 return false;
1326 }
1327
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001328 if(mCurrentFrame.fbCount)
1329 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001330
Raj Kamal389d6e32014-08-04 14:43:24 +05301331 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001332 adjustForSourceSplit(ctx, list);
1333 }
1334
1335 if(!postHeuristicsHandling(ctx, list)) {
1336 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301337 if(errno == ENOBUFS) {
1338 ALOGD_IF(isDebug(), "SMP Allocation failed");
1339 //On SMP allocation failure in video only comp add padding round
1340 ctx->isPaddingRound = true;
1341 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001342 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001343 return false;
1344 }
1345
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001346 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1347 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001348 return true;
1349}
1350
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001351/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1352bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1353 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001354 // Fall back to video only composition, if AIV video mode is enabled
1355 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001356 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1357 __FUNCTION__, mDpy);
1358 return false;
1359 }
1360
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001361 const bool secureOnly = true;
1362 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1363 mdpOnlyLayersComp(ctx, list, secureOnly);
1364
1365}
1366
1367bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1368 hwc_display_contents_1_t* list, bool secureOnly) {
1369
1370 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1371 return false;
1372
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301373 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1374 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1375 /* Bail out if we are processing only secured video/ui layers
1376 * and we dont have any */
1377 if(secureOnly) {
1378 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1379 return false;
1380 }
1381 /* No Idle fall back for secure video/ui layers and if there is only
1382 * single layer being composed. */
1383 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1384 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1385 return false;
1386 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001387 }
1388
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001389 /* Bail out if we dont have any secure RGB layers */
1390 if (!ctx->listStats[mDpy].secureRGBCount) {
1391 reset(ctx);
1392 return false;
1393 }
1394
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001395 mCurrentFrame.reset(numAppLayers);
1396 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1397
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001398 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001399 /* mark secure RGB layers for MDP comp */
1400 updateSecureRGB(ctx, list);
1401
1402 if(mCurrentFrame.mdpCount == 0) {
1403 reset(ctx);
1404 return false;
1405 }
1406
1407 /* find the maximum batch of layers to be marked for framebuffer */
1408 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1409 if(!ret) {
1410 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1411 reset(ctx);
1412 return false;
1413 }
1414
1415 if(sEnableYUVsplit){
1416 adjustForSourceSplit(ctx, list);
1417 }
1418
1419 if(!postHeuristicsHandling(ctx, list)) {
1420 ALOGD_IF(isDebug(), "post heuristic handling failed");
1421 reset(ctx);
1422 return false;
1423 }
1424
1425 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1426 __FUNCTION__);
1427 return true;
1428}
1429
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001430/* Checks for conditions where YUV layers cannot be bypassed */
1431bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001432 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001433 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001434 return false;
1435 }
1436
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001437 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001438 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1439 return false;
1440 }
1441
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001442 if(isSecuring(ctx, layer)) {
1443 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1444 return false;
1445 }
1446
Saurabh Shah4fdde762013-04-30 18:47:33 -07001447 if(!isValidDimension(ctx, layer)) {
1448 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1449 __FUNCTION__);
1450 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001451 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001452
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001453 if(layer->planeAlpha < 0xFF) {
1454 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1455 in video only mode",
1456 __FUNCTION__);
1457 return false;
1458 }
1459
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001460 return true;
1461}
1462
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001463/* Checks for conditions where Secure RGB layers cannot be bypassed */
1464bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1465 if(isSkipLayer(layer)) {
1466 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1467 __FUNCTION__, mDpy);
1468 return false;
1469 }
1470
1471 if(isSecuring(ctx, layer)) {
1472 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1473 return false;
1474 }
1475
1476 if(not isSupportedForMDPComp(ctx, layer)) {
1477 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1478 __FUNCTION__);
1479 return false;
1480 }
1481 return true;
1482}
1483
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301484/* starts at fromIndex and check for each layer to find
1485 * if it it has overlapping with any Updating layer above it in zorder
1486 * till the end of the batch. returns true if it finds any intersection */
1487bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1488 int fromIndex, int toIndex) {
1489 for(int i = fromIndex; i < toIndex; i++) {
1490 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1491 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1492 return false;
1493 }
1494 }
1495 }
1496 return true;
1497}
1498
1499/* Checks if given layer at targetLayerIndex has any
1500 * intersection with all the updating layers in beween
1501 * fromIndex and toIndex. Returns true if it finds intersectiion */
1502bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1503 int fromIndex, int toIndex, int targetLayerIndex) {
1504 for(int i = fromIndex; i <= toIndex; i++) {
1505 if(!mCurrentFrame.isFBComposed[i]) {
1506 if(areLayersIntersecting(&list->hwLayers[i],
1507 &list->hwLayers[targetLayerIndex])) {
1508 return true;
1509 }
1510 }
1511 }
1512 return false;
1513}
1514
1515int MDPComp::getBatch(hwc_display_contents_1_t* list,
1516 int& maxBatchStart, int& maxBatchEnd,
1517 int& maxBatchCount) {
1518 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301519 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001520 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301521 while (i < mCurrentFrame.layerCount) {
1522 int batchCount = 0;
1523 int batchStart = i;
1524 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001525 /* Adjust batch Z order with the dropped layers so far */
1526 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301527 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301528 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301529 while(i < mCurrentFrame.layerCount) {
1530 if(!mCurrentFrame.isFBComposed[i]) {
1531 if(!batchCount) {
1532 i++;
1533 break;
1534 }
1535 updatingLayersAbove++;
1536 i++;
1537 continue;
1538 } else {
1539 if(mCurrentFrame.drop[i]) {
1540 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001541 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301542 continue;
1543 } else if(updatingLayersAbove <= 0) {
1544 batchCount++;
1545 batchEnd = i;
1546 i++;
1547 continue;
1548 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1549
1550 // We have a valid updating layer already. If layer-i not
1551 // have overlapping with all updating layers in between
1552 // batch-start and i, then we can add layer i to batch.
1553 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1554 batchCount++;
1555 batchEnd = i;
1556 i++;
1557 continue;
1558 } else if(canPushBatchToTop(list, batchStart, i)) {
1559 //If All the non-updating layers with in this batch
1560 //does not have intersection with the updating layers
1561 //above in z-order, then we can safely move the batch to
1562 //higher z-order. Increment fbZ as it is moving up.
1563 if( firstZReverseIndex < 0) {
1564 firstZReverseIndex = i;
1565 }
1566 batchCount++;
1567 batchEnd = i;
1568 fbZ += updatingLayersAbove;
1569 i++;
1570 updatingLayersAbove = 0;
1571 continue;
1572 } else {
1573 //both failed.start the loop again from here.
1574 if(firstZReverseIndex >= 0) {
1575 i = firstZReverseIndex;
1576 }
1577 break;
1578 }
1579 }
1580 }
1581 }
1582 if(batchCount > maxBatchCount) {
1583 maxBatchCount = batchCount;
1584 maxBatchStart = batchStart;
1585 maxBatchEnd = batchEnd;
1586 fbZOrder = fbZ;
1587 }
1588 }
1589 return fbZOrder;
1590}
1591
1592bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1593 hwc_display_contents_1_t* list) {
1594 /* Idea is to keep as many non-updating(cached) layers in FB and
1595 * send rest of them through MDP. This is done in 2 steps.
1596 * 1. Find the maximum contiguous batch of non-updating layers.
1597 * 2. See if we can improve this batch size for caching by adding
1598 * opaque layers around the batch, if they don't have
1599 * any overlapping with the updating layers in between.
1600 * NEVER mark an updating layer for caching.
1601 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602
1603 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001604 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001605 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301606 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001607
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001608 /* Nothing is cached. No batching needed */
1609 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001610 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001611 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001612
1613 /* No MDP comp layers, try to use other comp modes */
1614 if(mCurrentFrame.mdpCount == 0) {
1615 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001616 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001617
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301618 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001619
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301620 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001622 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001623 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301624 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001625 if(!mCurrentFrame.drop[i]){
1626 //If an unsupported layer is being attempted to
1627 //be pulled out we should fail
1628 if(not isSupportedForMDPComp(ctx, layer)) {
1629 return false;
1630 }
1631 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001632 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001633 }
1634 }
1635
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301636 // update the frame data
1637 mCurrentFrame.fbZ = fbZ;
1638 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001639 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001640 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001641
1642 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301643 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001644
1645 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001646}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001647
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001648void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001649 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001650 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001651 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001652
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001653 for(int i = 0; i < numAppLayers; i++) {
1654 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001655 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001656 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001657 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001659 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660 }
1661 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001662
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001663 frame.fbCount = fbCount;
1664 frame.mdpCount = frame.layerCount - frame.fbCount
1665 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001666
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001667 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1668 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001669}
1670
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001671// drop other non-AIV layers from external display list.
1672void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001673 hwc_display_contents_1_t* list) {
1674 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1675 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001676 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001677 mCurrentFrame.dropCount++;
1678 mCurrentFrame.drop[i] = true;
1679 }
1680 }
1681 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1682 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1683 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1684 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1685 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1686 mCurrentFrame.dropCount);
1687}
1688
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001689void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001690 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001691 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1692 for(int index = 0;index < nYuvCount; index++){
1693 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1694 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1695
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001696 if(mCurrentFrame.drop[nYuvIndex]) {
1697 continue;
1698 }
1699
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001700 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001701 if(!frame.isFBComposed[nYuvIndex]) {
1702 frame.isFBComposed[nYuvIndex] = true;
1703 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001704 }
1705 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001706 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001707 private_handle_t *hnd = (private_handle_t *)layer->handle;
1708 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001709 frame.isFBComposed[nYuvIndex] = false;
1710 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001711 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001712 }
1713 }
1714 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001715
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001716 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1717 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001718}
1719
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001720void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1721 hwc_display_contents_1_t* list) {
1722 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1723 for(int index = 0;index < nSecureRGBCount; index++){
1724 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1725 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1726
1727 if(!isSecureRGBDoable(ctx, layer)) {
1728 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1729 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1730 mCurrentFrame.fbCount++;
1731 }
1732 } else {
1733 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1734 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1735 mCurrentFrame.fbCount--;
1736 }
1737 }
1738 }
1739
1740 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1741 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1742 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1743 mCurrentFrame.fbCount);
1744}
1745
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001746hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1747 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001748 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001749
1750 /* Update only the region of FB needed for composition */
1751 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1752 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1753 hwc_layer_1_t* layer = &list->hwLayers[i];
1754 hwc_rect_t dst = layer->displayFrame;
1755 fbRect = getUnion(fbRect, dst);
1756 }
1757 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001758 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001759 return fbRect;
1760}
1761
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001762bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1763 hwc_display_contents_1_t* list) {
1764
1765 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001766 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001767 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1768 return false;
1769 }
1770
1771 //Limitations checks
1772 if(!hwLimitationsCheck(ctx, list)) {
1773 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1774 return false;
1775 }
1776
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001777 //Configure framebuffer first if applicable
1778 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001779 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001780 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1781 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001782 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1783 __FUNCTION__);
1784 return false;
1785 }
1786 }
1787
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001788 mCurrentFrame.map();
1789
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001790 if(!allocLayerPipes(ctx, list)) {
1791 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001792 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001793 }
1794
1795 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001796 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001797 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001798 int mdpIndex = mCurrentFrame.layerToMDP[index];
1799 hwc_layer_1_t* layer = &list->hwLayers[index];
1800
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301801 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1802 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1803 mdpNextZOrder++;
1804 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001805 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1806 cur_pipe->zOrder = mdpNextZOrder++;
1807
radhakrishnac9a67412013-09-25 17:40:42 +05301808 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301809 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301810 if(configure4k2kYuv(ctx, layer,
1811 mCurrentFrame.mdpToLayer[mdpIndex])
1812 != 0 ){
1813 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1814 for layer %d",__FUNCTION__, index);
1815 return false;
1816 }
1817 else{
1818 mdpNextZOrder++;
1819 }
1820 continue;
1821 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001822 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1823 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301824 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001825 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001826 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001827 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001828 }
1829
Saurabh Shaha36be922013-12-16 18:18:39 -08001830 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1831 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1832 ,__FUNCTION__, mDpy);
1833 return false;
1834 }
1835
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001836 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001837 return true;
1838}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001839
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001840bool MDPComp::resourceCheck(hwc_context_t* ctx,
1841 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001842 const bool fbUsed = mCurrentFrame.fbCount;
1843 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1844 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1845 return false;
1846 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001847
1848 //Will benefit cases where a video has non-updating background.
1849 if((mDpy > HWC_DISPLAY_PRIMARY) and
1850 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1851 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1852 return false;
1853 }
1854
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001855 // Init rotCount to number of rotate sessions used by other displays
1856 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1857 // Count the number of rotator sessions required for current display
1858 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1859 if(!mCurrentFrame.isFBComposed[index]) {
1860 hwc_layer_1_t* layer = &list->hwLayers[index];
1861 private_handle_t *hnd = (private_handle_t *)layer->handle;
1862 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1863 rotCount++;
1864 }
1865 }
1866 }
1867 // if number of layers to rotate exceeds max rotator sessions, bail out.
1868 if(rotCount > RotMgr::MAX_ROT_SESS) {
1869 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1870 __FUNCTION__, mDpy);
1871 return false;
1872 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001873 return true;
1874}
1875
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301876bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1877 hwc_display_contents_1_t* list) {
1878
1879 //A-family hw limitation:
1880 //If a layer need alpha scaling, MDP can not support.
1881 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1882 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1883 if(!mCurrentFrame.isFBComposed[i] &&
1884 isAlphaScaled( &list->hwLayers[i])) {
1885 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1886 return false;
1887 }
1888 }
1889 }
1890
1891 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1892 //If multiple layers requires downscaling and also they are overlapping
1893 //fall back to GPU since MDSS can not handle it.
1894 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1895 qdutils::MDPVersion::getInstance().is8x26()) {
1896 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1897 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1898 if(!mCurrentFrame.isFBComposed[i] &&
1899 isDownscaleRequired(botLayer)) {
1900 //if layer-i is marked for MDP and needs downscaling
1901 //check if any MDP layer on top of i & overlaps with layer-i
1902 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1903 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1904 if(!mCurrentFrame.isFBComposed[j] &&
1905 isDownscaleRequired(topLayer)) {
1906 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1907 topLayer->displayFrame);
1908 if(isValidRect(r))
1909 return false;
1910 }
1911 }
1912 }
1913 }
1914 }
1915 return true;
1916}
1917
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001918// Checks only if videos or single layer(RGB) is updating
1919// which is used for setting dynamic fps or perf hint for single
1920// layer video playback
1921bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1922 hwc_display_contents_1_t* list) {
1923 bool support = false;
1924 FrameInfo frame;
1925 frame.reset(mCurrentFrame.layerCount);
1926 memset(&frame.drop, 0, sizeof(frame.drop));
1927 frame.dropCount = 0;
1928 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1929 updateLayerCache(ctx, list, frame);
1930 updateYUV(ctx, list, false /*secure only*/, frame);
1931 // There are only updating YUV layers or there is single RGB
1932 // Layer(Youtube)
1933 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1934 (frame.layerCount == 1)) {
1935 support = true;
1936 }
1937 return support;
1938}
1939
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301940void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1941 //For primary display, set the dynamic refreshrate
1942 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1943 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301944 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1945 MDPVersion& mdpHw = MDPVersion::getInstance();
1946 if(sIdleFallBack) {
1947 //Set minimum panel refresh rate during idle timeout
1948 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001949 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301950 //Set the new fresh rate, if there is only one updating YUV layer
1951 //or there is one single RGB layer with this request
1952 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1953 }
1954 setRefreshRate(ctx, mDpy, refreshRate);
1955 }
1956}
1957
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001958int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001959 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001960 char property[PROPERTY_VALUE_MAX];
1961
Raj Kamal4393eaa2014-06-06 13:45:20 +05301962 if(!ctx || !list) {
1963 ALOGE("%s: Invalid context or list",__FUNCTION__);
1964 mCachedFrame.reset();
1965 return -1;
1966 }
1967
1968 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001969 if(mDpy == HWC_DISPLAY_PRIMARY) {
1970 sSimulationFlags = 0;
1971 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1972 int currentFlags = atoi(property);
1973 if(currentFlags != sSimulationFlags) {
1974 sSimulationFlags = currentFlags;
1975 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1976 sSimulationFlags, sSimulationFlags);
1977 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001978 }
1979 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001980 // reset PTOR
1981 if(!mDpy)
1982 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001983
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301984 //reset old data
1985 mCurrentFrame.reset(numLayers);
1986 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1987 mCurrentFrame.dropCount = 0;
1988
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301989 //Do not cache the information for next draw cycle.
1990 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1991 ALOGI("%s: Unsupported layer count for mdp composition",
1992 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001993 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301994#ifdef DYNAMIC_FPS
1995 setDynRefreshRate(ctx, list);
1996#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001997 return -1;
1998 }
1999
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002000 // Detect the start of animation and fall back to GPU only once to cache
2001 // all the layers in FB and display FB content untill animation completes.
2002 if(ctx->listStats[mDpy].isDisplayAnimating) {
2003 mCurrentFrame.needsRedraw = false;
2004 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2005 mCurrentFrame.needsRedraw = true;
2006 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2007 }
2008 setMDPCompLayerFlags(ctx, list);
2009 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302010#ifdef DYNAMIC_FPS
2011 setDynRefreshRate(ctx, list);
2012#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002013 ret = -1;
2014 return ret;
2015 } else {
2016 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2017 }
2018
Saurabh Shahb39f8152013-08-22 10:21:44 -07002019 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002020 if(isFrameDoable(ctx)) {
2021 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002022 // if AIV Video mode is enabled, drop all non AIV layers from the
2023 // external display list.
2024 if(ctx->listStats[mDpy].mAIVVideoMode) {
2025 dropNonAIVLayers(ctx, list);
2026 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002027
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002028 // if tryFullFrame fails, try to push all video and secure RGB layers
2029 // to MDP for composition.
2030 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002031 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302032 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002033 setMDPCompLayerFlags(ctx, list);
2034 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002035 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002036 reset(ctx);
2037 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2038 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002039 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002040 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2041 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002042 }
2043 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302044 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2045 enablePartialUpdateForMDP3) {
2046 generateROI(ctx, list);
2047 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2048 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2049 }
2050 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002051 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2052 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002053 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002054 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002055
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002056 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002057 ALOGD("GEOMETRY change: %d",
2058 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002059 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002060 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002061 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002062 }
2063
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002064#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302065 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002066#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002067 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002068
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002069 mCachedFrame.cacheAll(list);
2070 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002071 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002072}
2073
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002074bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302075
2076 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302077 int mdpIndex = mCurrentFrame.layerToMDP[index];
2078 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2079 info.pipeInfo = new MdpYUVPipeInfo;
2080 info.rot = NULL;
2081 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302082
2083 pipe_info.lIndex = ovutils::OV_INVALID;
2084 pipe_info.rIndex = ovutils::OV_INVALID;
2085
Saurabh Shahc62f3982014-03-05 14:28:26 -08002086 Overlay::PipeSpecs pipeSpecs;
2087 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2088 pipeSpecs.needsScaling = true;
2089 pipeSpecs.dpy = mDpy;
2090 pipeSpecs.fb = false;
2091
2092 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302093 if(pipe_info.lIndex == ovutils::OV_INVALID){
2094 bRet = false;
2095 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2096 __FUNCTION__);
2097 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002098 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302099 if(pipe_info.rIndex == ovutils::OV_INVALID){
2100 bRet = false;
2101 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2102 __FUNCTION__);
2103 }
2104 return bRet;
2105}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002106
2107int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2108 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002109 if (ctx->mPtorInfo.isActive()) {
2110 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002111 if (fd < 0) {
2112 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002113 }
2114 }
2115 return fd;
2116}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002117//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002118
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002119void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302120 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002121 //If 4k2k Yuv layer split is possible, and if
2122 //fbz is above 4k2k layer, increment fb zorder by 1
2123 //as we split 4k2k layer and increment zorder for right half
2124 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002125 if(!ctx)
2126 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002127 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302128 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2129 index++) {
2130 if(!mCurrentFrame.isFBComposed[index]) {
2131 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2132 mdpNextZOrder++;
2133 }
2134 mdpNextZOrder++;
2135 hwc_layer_1_t* layer = &list->hwLayers[index];
2136 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302137 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302138 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2139 mCurrentFrame.fbZ += 1;
2140 mdpNextZOrder++;
2141 //As we split 4kx2k yuv layer and program to 2 VG pipes
2142 //(if available) increase mdpcount by 1.
2143 mCurrentFrame.mdpCount++;
2144 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002145 }
2146 }
2147 }
radhakrishnac9a67412013-09-25 17:40:42 +05302148}
2149
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002150/*
2151 * Configures pipe(s) for MDP composition
2152 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002153int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002154 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002155 MdpPipeInfoNonSplit& mdp_info =
2156 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302157 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002158 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002159 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002160
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002161 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2162 __FUNCTION__, layer, zOrder, dest);
2163
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002164 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002165 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002166}
2167
Saurabh Shah88e4d272013-09-03 13:31:29 -07002168bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002169 hwc_display_contents_1_t* list) {
2170 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002171
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002172 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002173
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002174 hwc_layer_1_t* layer = &list->hwLayers[index];
2175 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302176 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002177 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302178 continue;
2179 }
2180 }
2181
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002182 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002183 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002184 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002185 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002186 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002187
Saurabh Shahc62f3982014-03-05 14:28:26 -08002188 Overlay::PipeSpecs pipeSpecs;
2189 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2190 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2191 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2192 (qdutils::MDPVersion::getInstance().is8x26() and
2193 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2194 pipeSpecs.dpy = mDpy;
2195 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002196 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002197
Saurabh Shahc62f3982014-03-05 14:28:26 -08002198 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2199
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002200 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002201 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002202 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002203 }
2204 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002205 return true;
2206}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002207
radhakrishnac9a67412013-09-25 17:40:42 +05302208int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2209 PipeLayerPair& PipeLayerPair) {
2210 MdpYUVPipeInfo& mdp_info =
2211 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2212 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302213 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302214 eDest lDest = mdp_info.lIndex;
2215 eDest rDest = mdp_info.rIndex;
2216
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002217 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302218 lDest, rDest, &PipeLayerPair.rot);
2219}
2220
Saurabh Shah88e4d272013-09-03 13:31:29 -07002221bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002222
Raj Kamal4393eaa2014-06-06 13:45:20 +05302223 if(!isEnabled() or !mModeOn) {
2224 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302225 return true;
2226 }
2227
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002228 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002229 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002230 sHandleTimeout = true;
2231 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002232
2233 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002234 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002235
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002236 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2237 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002238 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002239 if(mCurrentFrame.isFBComposed[i]) continue;
2240
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002241 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002242 private_handle_t *hnd = (private_handle_t *)layer->handle;
2243 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002244 if (!(layer->flags & HWC_COLOR_FILL)) {
2245 ALOGE("%s handle null", __FUNCTION__);
2246 return false;
2247 }
2248 // No PLAY for Color layer
2249 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2250 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002251 }
2252
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002253 int mdpIndex = mCurrentFrame.layerToMDP[i];
2254
Raj Kamal389d6e32014-08-04 14:43:24 +05302255 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302256 {
2257 MdpYUVPipeInfo& pipe_info =
2258 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2259 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2260 ovutils::eDest indexL = pipe_info.lIndex;
2261 ovutils::eDest indexR = pipe_info.rIndex;
2262 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302263 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302264 if(rot) {
2265 rot->queueBuffer(fd, offset);
2266 fd = rot->getDstMemId();
2267 offset = rot->getDstOffset();
2268 }
2269 if(indexL != ovutils::OV_INVALID) {
2270 ovutils::eDest destL = (ovutils::eDest)indexL;
2271 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2272 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2273 if (!ov.queueBuffer(fd, offset, destL)) {
2274 ALOGE("%s: queueBuffer failed for display:%d",
2275 __FUNCTION__, mDpy);
2276 return false;
2277 }
2278 }
2279
2280 if(indexR != ovutils::OV_INVALID) {
2281 ovutils::eDest destR = (ovutils::eDest)indexR;
2282 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2283 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2284 if (!ov.queueBuffer(fd, offset, destR)) {
2285 ALOGE("%s: queueBuffer failed for display:%d",
2286 __FUNCTION__, mDpy);
2287 return false;
2288 }
2289 }
2290 }
2291 else{
2292 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002293 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302294 ovutils::eDest dest = pipe_info.index;
2295 if(dest == ovutils::OV_INVALID) {
2296 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002297 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302298 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002299
radhakrishnac9a67412013-09-25 17:40:42 +05302300 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2301 continue;
2302 }
2303
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002304 int fd = hnd->fd;
2305 uint32_t offset = (uint32_t)hnd->offset;
2306 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2307 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002308 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002309 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002310 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002311 }
2312
radhakrishnac9a67412013-09-25 17:40:42 +05302313 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2314 using pipe: %d", __FUNCTION__, layer,
2315 hnd, dest );
2316
radhakrishnac9a67412013-09-25 17:40:42 +05302317 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2318 if(rot) {
2319 if(!rot->queueBuffer(fd, offset))
2320 return false;
2321 fd = rot->getDstMemId();
2322 offset = rot->getDstOffset();
2323 }
2324
2325 if (!ov.queueBuffer(fd, offset, dest)) {
2326 ALOGE("%s: queueBuffer failed for display:%d ",
2327 __FUNCTION__, mDpy);
2328 return false;
2329 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002330 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002331
2332 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002333 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002334 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002335}
2336
Saurabh Shah88e4d272013-09-03 13:31:29 -07002337//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002338
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002339void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302340 hwc_display_contents_1_t* list){
2341 //if 4kx2k yuv layer is totally present in either in left half
2342 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302343 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302344 if(mCurrentFrame.fbZ >= 0) {
2345 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2346 index++) {
2347 if(!mCurrentFrame.isFBComposed[index]) {
2348 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2349 mdpNextZOrder++;
2350 }
2351 mdpNextZOrder++;
2352 hwc_layer_1_t* layer = &list->hwLayers[index];
2353 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302354 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302355 hwc_rect_t dst = layer->displayFrame;
2356 if((dst.left > lSplit) || (dst.right < lSplit)) {
2357 mCurrentFrame.mdpCount += 1;
2358 }
2359 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2360 mCurrentFrame.fbZ += 1;
2361 mdpNextZOrder++;
2362 }
2363 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002364 }
radhakrishnac9a67412013-09-25 17:40:42 +05302365 }
2366}
2367
Saurabh Shah88e4d272013-09-03 13:31:29 -07002368bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002369 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002370
Saurabh Shahc62f3982014-03-05 14:28:26 -08002371 const int lSplit = getLeftSplit(ctx, mDpy);
2372 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002373 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002374 pipe_info.lIndex = ovutils::OV_INVALID;
2375 pipe_info.rIndex = ovutils::OV_INVALID;
2376
Saurabh Shahc62f3982014-03-05 14:28:26 -08002377 Overlay::PipeSpecs pipeSpecs;
2378 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2379 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2380 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2381 pipeSpecs.dpy = mDpy;
2382 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2383 pipeSpecs.fb = false;
2384
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002385 // Acquire pipe only for the updating half
2386 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2387 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2388
2389 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002390 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002391 if(pipe_info.lIndex == ovutils::OV_INVALID)
2392 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002393 }
2394
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002395 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002396 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2397 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002398 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002399 return false;
2400 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002401
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002402 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002403}
2404
Saurabh Shah88e4d272013-09-03 13:31:29 -07002405bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002406 hwc_display_contents_1_t* list) {
2407 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002408
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002409 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002410
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002411 hwc_layer_1_t* layer = &list->hwLayers[index];
2412 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302413 hwc_rect_t dst = layer->displayFrame;
2414 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302415 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302416 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002417 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302418 continue;
2419 }
2420 }
2421 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002422 int mdpIndex = mCurrentFrame.layerToMDP[index];
2423 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002424 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002425 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002426 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002427
Saurabh Shahc62f3982014-03-05 14:28:26 -08002428 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2429 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2430 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002431 return false;
2432 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002433 }
2434 return true;
2435}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002436
radhakrishnac9a67412013-09-25 17:40:42 +05302437int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2438 PipeLayerPair& PipeLayerPair) {
2439 const int lSplit = getLeftSplit(ctx, mDpy);
2440 hwc_rect_t dst = layer->displayFrame;
2441 if((dst.left > lSplit)||(dst.right < lSplit)){
2442 MdpYUVPipeInfo& mdp_info =
2443 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2444 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302445 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302446 eDest lDest = mdp_info.lIndex;
2447 eDest rDest = mdp_info.rIndex;
2448
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002449 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302450 lDest, rDest, &PipeLayerPair.rot);
2451 }
2452 else{
2453 return configure(ctx, layer, PipeLayerPair);
2454 }
2455}
2456
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002457/*
2458 * Configures pipe(s) for MDP composition
2459 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002460int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002461 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002462 MdpPipeInfoSplit& mdp_info =
2463 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002464 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302465 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002466 eDest lDest = mdp_info.lIndex;
2467 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002468
2469 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002470 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002471
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002472 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002473 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002474}
2475
Saurabh Shah88e4d272013-09-03 13:31:29 -07002476bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002477
Raj Kamal4393eaa2014-06-06 13:45:20 +05302478 if(!isEnabled() or !mModeOn) {
2479 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302480 return true;
2481 }
2482
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002483 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002484 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002485 sHandleTimeout = true;
2486 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002487
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002488 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002489 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002490
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002491 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2492 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002493 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002494 if(mCurrentFrame.isFBComposed[i]) continue;
2495
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002496 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002497 private_handle_t *hnd = (private_handle_t *)layer->handle;
2498 if(!hnd) {
2499 ALOGE("%s handle null", __FUNCTION__);
2500 return false;
2501 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002502
2503 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2504 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002505 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002506
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002507 int mdpIndex = mCurrentFrame.layerToMDP[i];
2508
Raj Kamal389d6e32014-08-04 14:43:24 +05302509 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302510 {
2511 MdpYUVPipeInfo& pipe_info =
2512 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2513 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2514 ovutils::eDest indexL = pipe_info.lIndex;
2515 ovutils::eDest indexR = pipe_info.rIndex;
2516 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302517 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302518 if(rot) {
2519 rot->queueBuffer(fd, offset);
2520 fd = rot->getDstMemId();
2521 offset = rot->getDstOffset();
2522 }
2523 if(indexL != ovutils::OV_INVALID) {
2524 ovutils::eDest destL = (ovutils::eDest)indexL;
2525 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2526 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2527 if (!ov.queueBuffer(fd, offset, destL)) {
2528 ALOGE("%s: queueBuffer failed for display:%d",
2529 __FUNCTION__, mDpy);
2530 return false;
2531 }
2532 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002533
radhakrishnac9a67412013-09-25 17:40:42 +05302534 if(indexR != ovutils::OV_INVALID) {
2535 ovutils::eDest destR = (ovutils::eDest)indexR;
2536 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2537 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2538 if (!ov.queueBuffer(fd, offset, destR)) {
2539 ALOGE("%s: queueBuffer failed for display:%d",
2540 __FUNCTION__, mDpy);
2541 return false;
2542 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002543 }
2544 }
radhakrishnac9a67412013-09-25 17:40:42 +05302545 else{
2546 MdpPipeInfoSplit& pipe_info =
2547 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2548 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002549
radhakrishnac9a67412013-09-25 17:40:42 +05302550 ovutils::eDest indexL = pipe_info.lIndex;
2551 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002552
radhakrishnac9a67412013-09-25 17:40:42 +05302553 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002554 uint32_t offset = (uint32_t)hnd->offset;
2555 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2556 if (!mDpy && (index != -1)) {
2557 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2558 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002559 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002560 }
radhakrishnac9a67412013-09-25 17:40:42 +05302561
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002562 if(ctx->mAD->draw(ctx, fd, offset)) {
2563 fd = ctx->mAD->getDstFd();
2564 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002565 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002566
radhakrishnac9a67412013-09-25 17:40:42 +05302567 if(rot) {
2568 rot->queueBuffer(fd, offset);
2569 fd = rot->getDstMemId();
2570 offset = rot->getDstOffset();
2571 }
2572
2573 //************* play left mixer **********
2574 if(indexL != ovutils::OV_INVALID) {
2575 ovutils::eDest destL = (ovutils::eDest)indexL;
2576 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2577 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2578 if (!ov.queueBuffer(fd, offset, destL)) {
2579 ALOGE("%s: queueBuffer failed for left mixer",
2580 __FUNCTION__);
2581 return false;
2582 }
2583 }
2584
2585 //************* play right mixer **********
2586 if(indexR != ovutils::OV_INVALID) {
2587 ovutils::eDest destR = (ovutils::eDest)indexR;
2588 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2589 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2590 if (!ov.queueBuffer(fd, offset, destR)) {
2591 ALOGE("%s: queueBuffer failed for right mixer",
2592 __FUNCTION__);
2593 return false;
2594 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002595 }
2596 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002597
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002598 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2599 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002600
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002601 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002602}
Saurabh Shahab47c692014-02-12 18:45:57 -08002603
2604//================MDPCompSrcSplit==============================================
2605bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002606 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002607 private_handle_t *hnd = (private_handle_t *)layer->handle;
2608 hwc_rect_t dst = layer->displayFrame;
2609 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2610 pipe_info.lIndex = ovutils::OV_INVALID;
2611 pipe_info.rIndex = ovutils::OV_INVALID;
2612
2613 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2614 //should have a higher priority than the right one. Pipe priorities are
2615 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002616
Saurabh Shahc62f3982014-03-05 14:28:26 -08002617 Overlay::PipeSpecs pipeSpecs;
2618 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2619 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2620 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2621 pipeSpecs.dpy = mDpy;
2622 pipeSpecs.fb = false;
2623
Saurabh Shahab47c692014-02-12 18:45:57 -08002624 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002625 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002626 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002627 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002628 }
2629
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002630 /* Use 2 pipes IF
2631 a) Layer's crop width is > 2048 or
2632 b) Layer's dest width > 2048 or
2633 c) On primary, driver has indicated with caps to split always. This is
2634 based on an empirically derived value of panel height. Applied only
2635 if the layer's width is > mixer's width
2636 */
2637
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302638 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002639 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302640 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002641 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2642 const uint32_t dstWidth = dst.right - dst.left;
2643 const uint32_t dstHeight = dst.bottom - dst.top;
2644 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002645 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002646 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2647 crop.bottom - crop.top;
2648 //Approximation to actual clock, ignoring the common factors in pipe and
2649 //mixer cases like line_time
2650 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2651 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002652
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002653 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2654 //pipe line length, we are still using 2 pipes. This is fine just because
2655 //this is source split where destination doesn't matter. Evaluate later to
2656 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002657 if(dstWidth > mdpHw.getMaxPipeWidth() or
2658 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002659 (primarySplitAlways and
2660 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002661 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002662 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002663 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002664 }
2665
2666 // Return values
2667 // 1 Left pipe is higher priority, do nothing.
2668 // 0 Pipes of same priority.
2669 //-1 Right pipe is of higher priority, needs swap.
2670 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2671 pipe_info.rIndex) == -1) {
2672 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002673 }
2674 }
2675
2676 return true;
2677}
2678
Saurabh Shahab47c692014-02-12 18:45:57 -08002679int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2680 PipeLayerPair& PipeLayerPair) {
2681 private_handle_t *hnd = (private_handle_t *)layer->handle;
2682 if(!hnd) {
2683 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2684 return -1;
2685 }
2686 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2687 MdpPipeInfoSplit& mdp_info =
2688 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2689 Rotator **rot = &PipeLayerPair.rot;
2690 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002691 eDest lDest = mdp_info.lIndex;
2692 eDest rDest = mdp_info.rIndex;
2693 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2694 hwc_rect_t dst = layer->displayFrame;
2695 int transform = layer->transform;
2696 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002697 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002698 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002699 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2700
2701 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2702 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2703
2704 // Handle R/B swap
2705 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2706 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2707 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2708 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2709 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2710 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002711 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002712 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2713 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002714 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002715 /* Calculate the external display position based on MDP downscale,
2716 ActionSafe, and extorientation features. */
2717 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002718
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002719 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302720 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002721 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002722
2723 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2724 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002725 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002726 }
2727
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002728 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002729 (*rot) = ctx->mRotMgr->getNext();
2730 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002731 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002732 //If the video is using a single pipe, enable BWC
2733 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002734 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2735 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002736 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002737 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002738 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002739 ALOGE("%s: configRotator failed!", __FUNCTION__);
2740 return -1;
2741 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002742 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002743 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002744 }
2745
2746 //If 2 pipes being used, divide layer into half, crop and dst
2747 hwc_rect_t cropL = crop;
2748 hwc_rect_t cropR = crop;
2749 hwc_rect_t dstL = dst;
2750 hwc_rect_t dstR = dst;
2751 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2752 cropL.right = (crop.right + crop.left) / 2;
2753 cropR.left = cropL.right;
2754 sanitizeSourceCrop(cropL, cropR, hnd);
2755
Saurabh Shahb729b192014-08-15 18:04:24 -07002756 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002757 //Swap crops on H flip since 2 pipes are being used
2758 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2759 hwc_rect_t tmp = cropL;
2760 cropL = cropR;
2761 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002762 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002763 }
2764
Saurabh Shahb729b192014-08-15 18:04:24 -07002765 //cropSwap trick: If the src and dst widths are both odd, let us say
2766 //2507, then splitting both into half would cause left width to be 1253
2767 //and right 1254. If crop is swapped because of H flip, this will cause
2768 //left crop width to be 1254, whereas left dst width remains 1253, thus
2769 //inducing a scaling that is unaccounted for. To overcome that we add 1
2770 //to the dst width if there is a cropSwap. So if the original width was
2771 //2507, the left dst width will be 1254. Even if the original width was
2772 //even for ex: 2508, the left dst width will still remain 1254.
2773 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002774 dstR.left = dstL.right;
2775 }
2776
2777 //For the mdp, since either we are pre-rotating or MDP does flips
2778 orient = OVERLAY_TRANSFORM_0;
2779 transform = 0;
2780
2781 //configure left pipe
2782 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002783 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002784 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2785 (ovutils::eBlending) getBlending(layer->blending));
2786
2787 if(configMdp(ctx->mOverlay, pargL, orient,
2788 cropL, dstL, metadata, lDest) < 0) {
2789 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2790 return -1;
2791 }
2792 }
2793
2794 //configure right pipe
2795 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002796 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002797 static_cast<eRotFlags>(rotFlags),
2798 layer->planeAlpha,
2799 (ovutils::eBlending) getBlending(layer->blending));
2800 if(configMdp(ctx->mOverlay, pargR, orient,
2801 cropR, dstR, metadata, rDest) < 0) {
2802 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2803 return -1;
2804 }
2805 }
2806
2807 return 0;
2808}
2809
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002810bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2811 Locker::Autolock _l(ctx->mDrawLock);
2812 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2813 char path[MAX_SYSFS_FILE_PATH];
2814 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2815 int fd = open(path, O_RDONLY);
2816 if(fd < 0) {
2817 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2818 return -1;
2819 }
2820 char value[4];
2821 ssize_t size_read = read(fd, value, sizeof(value)-1);
2822 if(size_read <= 0) {
2823 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2824 close(fd);
2825 return -1;
2826 }
2827 close(fd);
2828 value[size_read] = '\0';
2829 return atoi(value);
2830}
2831
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002832int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2833 Locker::Autolock _l(ctx->mDrawLock);
2834 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2835 char path[MAX_SYSFS_FILE_PATH];
2836 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2837 int fd = open(path, O_WRONLY);
2838 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002839 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002840 return -1;
2841 }
2842 char value[4];
2843 snprintf(value, sizeof(value), "%d", (int)enable);
2844 ssize_t ret = write(fd, value, strlen(value));
2845 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002846 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002847 close(fd);
2848 return -1;
2849 }
2850 close(fd);
2851 sIsPartialUpdateActive = enable;
2852 return 0;
2853}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002854
2855bool MDPComp::loadPerfLib() {
2856 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2857 bool success = false;
2858 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2859 ALOGE("vendor library not set in ro.vendor.extension_library");
2860 return false;
2861 }
2862
2863 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
2864 if(sLibPerfHint) {
2865 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
2866 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
2867 if (!sPerfLockAcquire || !sPerfLockRelease) {
2868 ALOGE("Failed to load symbols for perfLock");
2869 dlclose(sLibPerfHint);
2870 sLibPerfHint = NULL;
2871 return false;
2872 }
2873 success = true;
2874 ALOGI("Successfully Loaded perf hint API's");
2875 } else {
2876 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
2877 }
2878 return success;
2879}
2880
2881void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2882 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
2883 return;
2884 }
2885 static int count = sPerfHintWindow;
2886 static int perflockFlag = 0;
2887
2888 /* Send hint to mpctl when single layer is updated
2889 * for a successful number of windows. Hint release
2890 * happens immediately upon multiple layer update.
2891 */
2892 if (onlyVideosUpdating(ctx, list)) {
2893 if(count) {
2894 count--;
2895 }
2896 } else {
2897 if (perflockFlag) {
2898 perflockFlag = 0;
2899 sPerfLockRelease(sPerfLockHandle);
2900 }
2901 count = sPerfHintWindow;
2902 }
2903 if (count == 0 && !perflockFlag) {
2904 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
2905 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
2906 &perfHint, sizeof(perfHint)/sizeof(int));
2907 if(sPerfLockHandle < 0) {
2908 ALOGE("Perf Lock Acquire Failed");
2909 } else {
2910 perflockFlag = 1;
2911 }
2912 }
2913}
2914
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002915}; //namespace
2916