blob: 7f31ad0b5631ec0a6cae56881c51374616719ff3 [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))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700393 (not isValidDimension(ctx,layer))
394 //More conditions here, SKIP, sRGB+Blend etc
395 ) {
396 return false;
397 }
398 return true;
399}
400
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530401bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800402 private_handle_t *hnd = (private_handle_t *)layer->handle;
403
404 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700405 if (layer->flags & HWC_COLOR_FILL) {
406 // Color layer
407 return true;
408 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700409 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return false;
411 }
412
Naseer Ahmede850a802013-09-06 13:12:52 -0400413 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400414 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400415 return false;
416
Saurabh Shah62e1d732013-09-17 10:44:05 -0700417 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700418 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700419 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700420 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
421 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700422 int dst_w = dst.right - dst.left;
423 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800424 float w_scale = ((float)crop_w / (float)dst_w);
425 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530426 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800428 /* Workaround for MDP HW limitation in DSI command mode panels where
429 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
430 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530431 * There also is a HW limilation in MDP, minimum block size is 2x2
432 * Fallback to GPU if height is less than 2.
433 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700434 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800435 return false;
436
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800437 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530438 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800439 const float w_dscale = w_scale;
440 const float h_dscale = h_scale;
441
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800442 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700443
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530444 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700445 /* On targets that doesnt support Decimation (eg.,8x26)
446 * maximum downscale support is overlay pipe downscale.
447 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800448 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530449 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700450 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800451 return false;
452 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700453 // Decimation on macrotile format layers is not supported.
454 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530455 /* Bail out if
456 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700457 * 2. exceeds maximum downscale limit
458 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800459 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530460 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700461 w_dscale > maxMDPDownscale ||
462 h_dscale > maxMDPDownscale) {
463 return false;
464 }
465 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800466 return false;
467 }
468 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700469 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700470 return false;
471 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700472 }
473
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800474 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530475 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800476 const float w_uscale = 1.0f / w_scale;
477 const float h_uscale = 1.0f / h_scale;
478
479 if(w_uscale > upscale || h_uscale > upscale)
480 return false;
481 }
482
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800483 return true;
484}
485
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800486bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700487 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800488
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800489 if(!isEnabled()) {
490 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700491 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530492 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530493 qdutils::MDPVersion::getInstance().is8x16() ||
494 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800495 ctx->mVideoTransFlag &&
496 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700497 //1 Padding round to shift pipes across mixers
498 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
499 __FUNCTION__);
500 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700501 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
502 /* TODO: freeing up all the resources only for the targets having total
503 number of pipes < 8. Need to analyze number of VIG pipes used
504 for primary in previous draw cycle and accordingly decide
505 whether to fall back to full GPU comp or video only comp
506 */
507 if(isSecondaryConfiguring(ctx)) {
508 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
509 __FUNCTION__);
510 ret = false;
511 } else if(ctx->isPaddingRound) {
512 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
513 __FUNCTION__,mDpy);
514 ret = false;
515 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800516 } else if (ctx->isDMAStateChanging) {
517 // Bail out if a padding round has been invoked in order to switch DMA
518 // state to block mode. We need this to cater for the case when a layer
519 // requires rotation in the current frame.
520 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
521 __FUNCTION__);
522 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700523 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800524
Saurabh Shahaa236822013-04-24 18:07:26 -0700525 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800526}
527
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800528void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
529 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
530 fbRect = getIntersection(fbRect, roi);
531}
532
533/* 1) Identify layers that are not visible or lying outside the updating ROI and
534 * drop them from composition.
535 * 2) If we have a scaling layer which needs cropping against generated
536 * ROI, reset ROI to full resolution. */
537bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
538 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700539 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800541
542 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800543 if(!isValidRect(visibleRect)) {
544 mCurrentFrame.drop[i] = true;
545 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800546 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800547 }
548
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700549 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800551 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700552
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700553 if(!isValidRect(res)) {
554 mCurrentFrame.drop[i] = true;
555 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800556 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700557 /* Reset frame ROI when any layer which needs scaling also needs ROI
558 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800559 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800560 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700561 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
562 mCurrentFrame.dropCount = 0;
563 return false;
564 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800565
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800566 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530567 if (layer->blending == HWC_BLENDING_NONE &&
568 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800569 visibleRect = deductRect(visibleRect, res);
570 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700571 }
572 return true;
573}
574
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800575/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
576 * are updating. If DirtyRegion is applicable, calculate it by accounting all
577 * the changing layer's dirtyRegion. */
578void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
579 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700580 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800581 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700582 return;
583
584 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800585 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
586 (int)ctx->dpyAttr[mDpy].yres};
587
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700588 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800589 hwc_layer_1_t* layer = &list->hwLayers[index];
590 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800591 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700592 hwc_rect_t dst = layer->displayFrame;
593 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800594
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800595#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800596 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700597 {
598 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
599 int x_off = dst.left - src.left;
600 int y_off = dst.top - src.top;
601 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
602 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800603#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800604
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800605 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700606 }
607 }
608
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800609 /* No layer is updating. Still SF wants a refresh.*/
610 if(!isValidRect(roi))
611 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800612
613 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800614 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800615
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800616 ctx->listStats[mDpy].lRoi = roi;
617 if(!validateAndApplyROI(ctx, list))
618 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700619
620 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800621 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
622 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
623}
624
625void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
626 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
627 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
628
629 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
630 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
631 fbRect = getUnion(l_fbRect, r_fbRect);
632}
633/* 1) Identify layers that are not visible or lying outside BOTH the updating
634 * ROI's and drop them from composition. If a layer is spanning across both
635 * the halves of the screen but needed by only ROI, the non-contributing
636 * half will not be programmed for MDP.
637 * 2) If we have a scaling layer which needs cropping against generated
638 * ROI, reset ROI to full resolution. */
639bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
640 hwc_display_contents_1_t* list) {
641
642 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
643
644 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
645 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
646
647 for(int i = numAppLayers - 1; i >= 0; i--){
648 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
649 {
650 mCurrentFrame.drop[i] = true;
651 mCurrentFrame.dropCount++;
652 continue;
653 }
654
655 const hwc_layer_1_t* layer = &list->hwLayers[i];
656 hwc_rect_t dstRect = layer->displayFrame;
657
658 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
659 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
660 hwc_rect_t res = getUnion(l_res, r_res);
661
662 if(!isValidRect(l_res) && !isValidRect(r_res)) {
663 mCurrentFrame.drop[i] = true;
664 mCurrentFrame.dropCount++;
665 } else {
666 /* Reset frame ROI when any layer which needs scaling also needs ROI
667 * cropping */
668 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
669 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
670 mCurrentFrame.dropCount = 0;
671 return false;
672 }
673
radhakrishna4efbdd62014-11-03 13:19:27 +0530674 if (layer->blending == HWC_BLENDING_NONE &&
675 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800676 visibleRectL = deductRect(visibleRectL, l_res);
677 visibleRectR = deductRect(visibleRectR, r_res);
678 }
679 }
680 }
681 return true;
682}
683/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
684 * are updating. If DirtyRegion is applicable, calculate it by accounting all
685 * the changing layer's dirtyRegion. */
686void MDPCompSplit::generateROI(hwc_context_t *ctx,
687 hwc_display_contents_1_t* list) {
688 if(!canPartialUpdate(ctx, list))
689 return;
690
691 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
692 int lSplit = getLeftSplit(ctx, mDpy);
693
694 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
695 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
696
697 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
698 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
699
700 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
701 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
702
703 for(int index = 0; index < numAppLayers; index++ ) {
704 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800705 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800706 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800707 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700708 hwc_rect_t dst = layer->displayFrame;
709 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800710
711#ifdef QCOM_BSP
712 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700713 {
714 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
715 int x_off = dst.left - src.left;
716 int y_off = dst.top - src.top;
717 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
718 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800719#endif
720
721 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
722 if(isValidRect(l_dst))
723 l_roi = getUnion(l_roi, l_dst);
724
725 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
726 if(isValidRect(r_dst))
727 r_roi = getUnion(r_roi, r_dst);
728 }
729 }
730
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700731 /* For panels that cannot accept commands in both the interfaces, we cannot
732 * send two ROI's (for each half). We merge them into single ROI and split
733 * them across lSplit for MDP mixer use. The ROI's will be merged again
734 * finally before udpating the panel in the driver. */
735 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
736 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
737 l_roi = getIntersection(temp_roi, l_frame);
738 r_roi = getIntersection(temp_roi, r_frame);
739 }
740
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800741 /* No layer is updating. Still SF wants a refresh. */
742 if(!isValidRect(l_roi) && !isValidRect(r_roi))
743 return;
744
745 l_roi = getSanitizeROI(l_roi, l_frame);
746 r_roi = getSanitizeROI(r_roi, r_frame);
747
748 ctx->listStats[mDpy].lRoi = l_roi;
749 ctx->listStats[mDpy].rRoi = r_roi;
750
751 if(!validateAndApplyROI(ctx, list))
752 resetROI(ctx, mDpy);
753
754 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
755 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
756 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
757 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
758 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
759 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700760}
761
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800762/* Checks for conditions where all the layers marked for MDP comp cannot be
763 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800764bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800765 hwc_display_contents_1_t* list){
766
Saurabh Shahaa236822013-04-24 18:07:26 -0700767 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800768
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700769 // Fall back to video only composition, if AIV video mode is enabled
770 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700771 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
772 __FUNCTION__, mDpy);
773 return false;
774 }
775
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530776 /* No Idle fall back if secure display or secure RGB layers are present
777 * or if there is only a single layer being composed */
778 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
779 !ctx->listStats[mDpy].secureRGBCount &&
780 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700781 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
782 return false;
783 }
784
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800785 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700786 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
787 __FUNCTION__,
788 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800789 return false;
790 }
791
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700792 // if secondary is configuring or Padding round, fall back to video only
793 // composition and release all assigned non VIG pipes from primary.
794 if(isSecondaryConfiguring(ctx)) {
795 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
796 __FUNCTION__);
797 return false;
798 } else if(ctx->isPaddingRound) {
799 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
800 __FUNCTION__,mDpy);
801 return false;
802 }
803
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700804 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800805 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700806 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800807 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
808 return false;
809 }
810
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800811 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800812 hwc_layer_1_t* layer = &list->hwLayers[i];
813 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800814
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800815 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700816 if(!canUseRotator(ctx, mDpy)) {
817 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
818 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700819 return false;
820 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800821 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530822
823 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
824 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800825 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700826 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530827 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
828 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
829 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800830 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700831
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700832 if(ctx->mAD->isDoable()) {
833 return false;
834 }
835
Saurabh Shahaa236822013-04-24 18:07:26 -0700836 //If all above hard conditions are met we can do full or partial MDP comp.
837 bool ret = false;
838 if(fullMDPComp(ctx, list)) {
839 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700840 } else if(fullMDPCompWithPTOR(ctx, list)) {
841 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700842 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700843 ret = true;
844 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530845
Saurabh Shahaa236822013-04-24 18:07:26 -0700846 return ret;
847}
848
849bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700850
851 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
852 return false;
853
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700854 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
855 for(int i = 0; i < numAppLayers; i++) {
856 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700857 if(not mCurrentFrame.drop[i] and
858 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700859 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
860 return false;
861 }
862 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800863
Saurabh Shahaa236822013-04-24 18:07:26 -0700864 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700865 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
866 sizeof(mCurrentFrame.isFBComposed));
867 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
868 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700869
Raj Kamal389d6e32014-08-04 14:43:24 +0530870 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800871 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530872 }
873
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800874 if(!postHeuristicsHandling(ctx, list)) {
875 ALOGD_IF(isDebug(), "post heuristic handling failed");
876 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700877 return false;
878 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700879 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
880 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700881 return true;
882}
883
Sushil Chauhandefd3522014-05-13 18:17:12 -0700884/* Full MDP Composition with Peripheral Tiny Overlap Removal.
885 * MDP bandwidth limitations can be avoided, if the overlap region
886 * covered by the smallest layer at a higher z-order, gets composed
887 * by Copybit on a render buffer, which can be queued to MDP.
888 */
889bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
890 hwc_display_contents_1_t* list) {
891
892 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
893 const int stagesForMDP = min(sMaxPipesPerMixer,
894 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
895
896 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700897 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700898 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
899 return false;
900 }
901
902 // Frame level checks
903 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
904 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
905 isSecurePresent(ctx, mDpy)) {
906 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
907 return false;
908 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700909 // MDP comp checks
910 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700912 if(not isSupportedForMDPComp(ctx, layer)) {
913 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
914 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700915 }
916 }
917
Sushil Chauhandefd3522014-05-13 18:17:12 -0700918 /* We cannot use this composition mode, if:
919 1. A below layer needs scaling.
920 2. Overlap is not peripheral to display.
921 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700922 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700923 */
924
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700925 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
926 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
927 memset(overlapRect, 0, sizeof(overlapRect));
928 int layerPixelCount, minPixelCount = 0;
929 int numPTORLayersFound = 0;
930 for (int i = numAppLayers-1; (i >= 0 &&
931 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700932 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700933 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700934 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700935 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
936 // PTOR layer should be peripheral and cannot have transform
937 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
938 has90Transform(layer)) {
939 continue;
940 }
941 if((3 * (layerPixelCount + minPixelCount)) >
942 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
943 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
944 continue;
945 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700946 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700947 for (int j = i-1; j >= 0; j--) {
948 // Check if the layers below this layer qualifies for PTOR comp
949 hwc_layer_1_t* layer = &list->hwLayers[j];
950 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700951 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700952 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700953 if (isValidRect(getIntersection(dispFrame, disFrame))) {
954 if (has90Transform(layer) || needsScaling(layer)) {
955 found = false;
956 break;
957 }
958 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700959 }
960 }
961 // Store the minLayer Index
962 if(found) {
963 minLayerIndex[numPTORLayersFound] = i;
964 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
965 minPixelCount += layerPixelCount;
966 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700967 }
968 }
969
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700970 // No overlap layers
971 if (!numPTORLayersFound)
972 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700973
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700974 // Store the displayFrame and the sourceCrops of the layers
975 hwc_rect_t displayFrame[numAppLayers];
976 hwc_rect_t sourceCrop[numAppLayers];
977 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700978 hwc_layer_1_t* layer = &list->hwLayers[i];
979 displayFrame[i] = layer->displayFrame;
980 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700981 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700982
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530983 /**
984 * It's possible that 2 PTOR layers might have overlapping.
985 * In such case, remove the intersection(again if peripheral)
986 * from the lower PTOR layer to avoid overlapping.
987 * If intersection is not on peripheral then compromise
988 * by reducing number of PTOR layers.
989 **/
990 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
991 if(isValidRect(commonRect)) {
992 overlapRect[1] = deductRect(overlapRect[1], commonRect);
993 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
994 }
995
996 ctx->mPtorInfo.count = numPTORLayersFound;
997 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
998 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
999 }
1000
1001 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1002 // reset PTOR
1003 ctx->mPtorInfo.count = 0;
1004 if(isValidRect(commonRect)) {
1005 // If PTORs are intersecting restore displayframe of PTOR[1]
1006 // before returning, as we have modified it above.
1007 list->hwLayers[minLayerIndex[1]].displayFrame =
1008 displayFrame[minLayerIndex[1]];
1009 }
1010 return false;
1011 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001012 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1013 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1014
Xu Yangcda012c2014-07-30 21:57:21 +08001015 // Store the blending mode, planeAlpha, and transform of PTOR layers
1016 int32_t blending[numPTORLayersFound];
1017 uint8_t planeAlpha[numPTORLayersFound];
1018 uint32_t transform[numPTORLayersFound];
1019
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001020 for(int j = 0; j < numPTORLayersFound; j++) {
1021 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001022
1023 // Update src crop of PTOR layer
1024 hwc_layer_1_t* layer = &list->hwLayers[index];
1025 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1026 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1027 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1028 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1029
1030 // Store & update w, h, format of PTOR layer
1031 private_handle_t *hnd = (private_handle_t *)layer->handle;
1032 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1033 layerWhf[j] = whf;
1034 hnd->width = renderBuf->width;
1035 hnd->height = renderBuf->height;
1036 hnd->format = renderBuf->format;
1037
Xu Yangcda012c2014-07-30 21:57:21 +08001038 // Store & update blending mode, planeAlpha and transform of PTOR layer
1039 blending[j] = layer->blending;
1040 planeAlpha[j] = layer->planeAlpha;
1041 transform[j] = layer->transform;
1042 layer->blending = HWC_BLENDING_NONE;
1043 layer->planeAlpha = 0xFF;
1044 layer->transform = 0;
1045
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001046 // Remove overlap from crop & displayFrame of below layers
1047 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001048 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001049 if(!isValidRect(getIntersection(layer->displayFrame,
1050 overlapRect[j]))) {
1051 continue;
1052 }
1053 // Update layer attributes
1054 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1055 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301056 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001057 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1058 layer->transform);
1059 layer->sourceCropf.left = (float)srcCrop.left;
1060 layer->sourceCropf.top = (float)srcCrop.top;
1061 layer->sourceCropf.right = (float)srcCrop.right;
1062 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1063 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001064 }
1065
1066 mCurrentFrame.mdpCount = numAppLayers;
1067 mCurrentFrame.fbCount = 0;
1068 mCurrentFrame.fbZ = -1;
1069
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301070 for (int j = 0; j < numAppLayers; j++) {
1071 if(isValidRect(list->hwLayers[j].displayFrame)) {
1072 mCurrentFrame.isFBComposed[j] = false;
1073 } else {
1074 mCurrentFrame.mdpCount--;
1075 mCurrentFrame.drop[j] = true;
1076 }
1077 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001078
1079 bool result = postHeuristicsHandling(ctx, list);
1080
1081 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001082 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001083 hwc_layer_1_t* layer = &list->hwLayers[i];
1084 layer->displayFrame = displayFrame[i];
1085 layer->sourceCropf.left = (float)sourceCrop[i].left;
1086 layer->sourceCropf.top = (float)sourceCrop[i].top;
1087 layer->sourceCropf.right = (float)sourceCrop[i].right;
1088 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1089 }
1090
Xu Yangcda012c2014-07-30 21:57:21 +08001091 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001092 for (int i = 0; i < numPTORLayersFound; i++) {
1093 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001094 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001095 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1096 hnd->width = layerWhf[i].w;
1097 hnd->height = layerWhf[i].h;
1098 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001099 layer->blending = blending[i];
1100 layer->planeAlpha = planeAlpha[i];
1101 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001102 }
1103
Sushil Chauhandefd3522014-05-13 18:17:12 -07001104 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001105 // reset PTOR
1106 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001107 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001108 } else {
1109 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1110 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001111 }
1112
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001113 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1114 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001115 return result;
1116}
1117
Saurabh Shahaa236822013-04-24 18:07:26 -07001118bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1119{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001120 if(!sEnableMixedMode) {
1121 //Mixed mode is disabled. No need to even try caching.
1122 return false;
1123 }
1124
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001125 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001126 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001127 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001128 cacheBasedComp(ctx, list);
1129 } else {
1130 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001131 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001132 }
1133
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001134 return ret;
1135}
1136
1137bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1138 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001139 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1140 return false;
1141
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001142 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001143 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001144 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001145
1146 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1147 for(int i = 0; i < numAppLayers; i++) {
1148 if(!mCurrentFrame.isFBComposed[i]) {
1149 hwc_layer_1_t* layer = &list->hwLayers[i];
1150 if(not isSupportedForMDPComp(ctx, layer)) {
1151 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1152 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001153 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001154 return false;
1155 }
1156 }
1157 }
1158
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001159 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001160 /* mark secure RGB layers for MDP comp */
1161 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301162 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001163 if(!ret) {
1164 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001165 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001166 return false;
1167 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001168
1169 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001170
Raj Kamal389d6e32014-08-04 14:43:24 +05301171 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001172 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301173 }
1174
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001175 if(!postHeuristicsHandling(ctx, list)) {
1176 ALOGD_IF(isDebug(), "post heuristic handling failed");
1177 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001178 return false;
1179 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001180 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1181 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001182
Saurabh Shahaa236822013-04-24 18:07:26 -07001183 return true;
1184}
1185
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001186bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001187 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001188 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1189 return false;
1190
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001191 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001192 return false;
1193 }
1194
Saurabh Shahb772ae32013-11-18 15:40:02 -08001195 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001196 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1197 const int stagesForMDP = min(sMaxPipesPerMixer,
1198 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001199
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001200 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1201 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1202 int lastMDPSupportedIndex = numAppLayers;
1203 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001204
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001205 //Find the minimum MDP batch size
1206 for(int i = 0; i < numAppLayers;i++) {
1207 if(mCurrentFrame.drop[i]) {
1208 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001209 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001210 }
1211 hwc_layer_1_t* layer = &list->hwLayers[i];
1212 if(not isSupportedForMDPComp(ctx, layer)) {
1213 lastMDPSupportedIndex = i;
1214 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1215 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001216 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001217 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001218 }
1219
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001220 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1221 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1222 mCurrentFrame.dropCount);
1223
1224 //Start at a point where the fb batch should at least have 2 layers, for
1225 //this mode to be justified.
1226 while(fbBatchSize < 2) {
1227 ++fbBatchSize;
1228 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001229 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001230
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001231 //If there are no layers for MDP, this mode doesnt make sense.
1232 if(mdpBatchSize < 1) {
1233 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1234 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001235 return false;
1236 }
1237
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001238 mCurrentFrame.reset(numAppLayers);
1239
1240 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1241 while(mdpBatchSize > 0) {
1242 //Mark layers for MDP comp
1243 int mdpBatchLeft = mdpBatchSize;
1244 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1245 if(mCurrentFrame.drop[i]) {
1246 continue;
1247 }
1248 mCurrentFrame.isFBComposed[i] = false;
1249 --mdpBatchLeft;
1250 }
1251
1252 mCurrentFrame.fbZ = mdpBatchSize;
1253 mCurrentFrame.fbCount = fbBatchSize;
1254 mCurrentFrame.mdpCount = mdpBatchSize;
1255
1256 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1257 __FUNCTION__, mdpBatchSize, fbBatchSize,
1258 mCurrentFrame.dropCount);
1259
1260 if(postHeuristicsHandling(ctx, list)) {
1261 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001262 __FUNCTION__);
1263 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1264 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001265 return true;
1266 }
1267
1268 reset(ctx);
1269 --mdpBatchSize;
1270 ++fbBatchSize;
1271 }
1272
1273 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001274}
1275
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001276bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301277 if(mDpy or isSecurePresent(ctx, mDpy) or
1278 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001279 return false;
1280 }
1281 return true;
1282}
1283
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001284bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1285 hwc_display_contents_1_t* list){
1286 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1287 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001288 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001289 return false;
1290 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001291 if(ctx->listStats[mDpy].secureUI)
1292 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001293 return true;
1294}
1295
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001296bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1297 hwc_display_contents_1_t* list) {
1298 const bool secureOnly = true;
1299 return videoOnlyComp(ctx, list, not secureOnly) or
1300 videoOnlyComp(ctx, list, secureOnly);
1301}
1302
1303bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001304 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001305 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1306 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301307
Saurabh Shahaa236822013-04-24 18:07:26 -07001308 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301309 if(!isSecurePresent(ctx, mDpy)) {
1310 /* Bail out if we are processing only secured video layers
1311 * and we dont have any */
1312 if(secureOnly) {
1313 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1314 return false;
1315 }
1316 /* No Idle fall back for secure video layers and if there is only
1317 * single layer being composed. */
1318 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1319 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1320 return false;
1321 }
1322 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001323
Saurabh Shahaa236822013-04-24 18:07:26 -07001324 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001325 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001326 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001327 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001328
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001329 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1330 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001331 return false;
1332 }
1333
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001334 if(mCurrentFrame.fbCount)
1335 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001336
Raj Kamal389d6e32014-08-04 14:43:24 +05301337 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001338 adjustForSourceSplit(ctx, list);
1339 }
1340
1341 if(!postHeuristicsHandling(ctx, list)) {
1342 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301343 if(errno == ENOBUFS) {
1344 ALOGD_IF(isDebug(), "SMP Allocation failed");
1345 //On SMP allocation failure in video only comp add padding round
1346 ctx->isPaddingRound = true;
1347 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001348 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001349 return false;
1350 }
1351
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001352 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1353 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001354 return true;
1355}
1356
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001357/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1358bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1359 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001360 // Fall back to video only composition, if AIV video mode is enabled
1361 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001362 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1363 __FUNCTION__, mDpy);
1364 return false;
1365 }
1366
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001367 const bool secureOnly = true;
1368 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1369 mdpOnlyLayersComp(ctx, list, secureOnly);
1370
1371}
1372
1373bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1374 hwc_display_contents_1_t* list, bool secureOnly) {
1375
1376 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1377 return false;
1378
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301379 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1380 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1381 /* Bail out if we are processing only secured video/ui layers
1382 * and we dont have any */
1383 if(secureOnly) {
1384 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1385 return false;
1386 }
1387 /* No Idle fall back for secure video/ui layers and if there is only
1388 * single layer being composed. */
1389 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1390 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1391 return false;
1392 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001393 }
1394
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001395 /* Bail out if we dont have any secure RGB layers */
1396 if (!ctx->listStats[mDpy].secureRGBCount) {
1397 reset(ctx);
1398 return false;
1399 }
1400
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001401 mCurrentFrame.reset(numAppLayers);
1402 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1403
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001404 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001405 /* mark secure RGB layers for MDP comp */
1406 updateSecureRGB(ctx, list);
1407
1408 if(mCurrentFrame.mdpCount == 0) {
1409 reset(ctx);
1410 return false;
1411 }
1412
1413 /* find the maximum batch of layers to be marked for framebuffer */
1414 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1415 if(!ret) {
1416 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1417 reset(ctx);
1418 return false;
1419 }
1420
1421 if(sEnableYUVsplit){
1422 adjustForSourceSplit(ctx, list);
1423 }
1424
1425 if(!postHeuristicsHandling(ctx, list)) {
1426 ALOGD_IF(isDebug(), "post heuristic handling failed");
1427 reset(ctx);
1428 return false;
1429 }
1430
1431 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1432 __FUNCTION__);
1433 return true;
1434}
1435
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001436/* Checks for conditions where YUV layers cannot be bypassed */
1437bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001438 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001439 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001440 return false;
1441 }
1442
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001443 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001444 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1445 return false;
1446 }
1447
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001448 if(isSecuring(ctx, layer)) {
1449 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1450 return false;
1451 }
1452
Saurabh Shah4fdde762013-04-30 18:47:33 -07001453 if(!isValidDimension(ctx, layer)) {
1454 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1455 __FUNCTION__);
1456 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001457 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001458
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001459 if(layer->planeAlpha < 0xFF) {
1460 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1461 in video only mode",
1462 __FUNCTION__);
1463 return false;
1464 }
1465
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001466 return true;
1467}
1468
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001469/* Checks for conditions where Secure RGB layers cannot be bypassed */
1470bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1471 if(isSkipLayer(layer)) {
1472 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1473 __FUNCTION__, mDpy);
1474 return false;
1475 }
1476
1477 if(isSecuring(ctx, layer)) {
1478 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1479 return false;
1480 }
1481
1482 if(not isSupportedForMDPComp(ctx, layer)) {
1483 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1484 __FUNCTION__);
1485 return false;
1486 }
1487 return true;
1488}
1489
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301490/* starts at fromIndex and check for each layer to find
1491 * if it it has overlapping with any Updating layer above it in zorder
1492 * till the end of the batch. returns true if it finds any intersection */
1493bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1494 int fromIndex, int toIndex) {
1495 for(int i = fromIndex; i < toIndex; i++) {
1496 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1497 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1498 return false;
1499 }
1500 }
1501 }
1502 return true;
1503}
1504
1505/* Checks if given layer at targetLayerIndex has any
1506 * intersection with all the updating layers in beween
1507 * fromIndex and toIndex. Returns true if it finds intersectiion */
1508bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1509 int fromIndex, int toIndex, int targetLayerIndex) {
1510 for(int i = fromIndex; i <= toIndex; i++) {
1511 if(!mCurrentFrame.isFBComposed[i]) {
1512 if(areLayersIntersecting(&list->hwLayers[i],
1513 &list->hwLayers[targetLayerIndex])) {
1514 return true;
1515 }
1516 }
1517 }
1518 return false;
1519}
1520
1521int MDPComp::getBatch(hwc_display_contents_1_t* list,
1522 int& maxBatchStart, int& maxBatchEnd,
1523 int& maxBatchCount) {
1524 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301525 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001526 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301527 while (i < mCurrentFrame.layerCount) {
1528 int batchCount = 0;
1529 int batchStart = i;
1530 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001531 /* Adjust batch Z order with the dropped layers so far */
1532 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301533 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301534 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301535 while(i < mCurrentFrame.layerCount) {
1536 if(!mCurrentFrame.isFBComposed[i]) {
1537 if(!batchCount) {
1538 i++;
1539 break;
1540 }
1541 updatingLayersAbove++;
1542 i++;
1543 continue;
1544 } else {
1545 if(mCurrentFrame.drop[i]) {
1546 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001547 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301548 continue;
1549 } else if(updatingLayersAbove <= 0) {
1550 batchCount++;
1551 batchEnd = i;
1552 i++;
1553 continue;
1554 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1555
1556 // We have a valid updating layer already. If layer-i not
1557 // have overlapping with all updating layers in between
1558 // batch-start and i, then we can add layer i to batch.
1559 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1560 batchCount++;
1561 batchEnd = i;
1562 i++;
1563 continue;
1564 } else if(canPushBatchToTop(list, batchStart, i)) {
1565 //If All the non-updating layers with in this batch
1566 //does not have intersection with the updating layers
1567 //above in z-order, then we can safely move the batch to
1568 //higher z-order. Increment fbZ as it is moving up.
1569 if( firstZReverseIndex < 0) {
1570 firstZReverseIndex = i;
1571 }
1572 batchCount++;
1573 batchEnd = i;
1574 fbZ += updatingLayersAbove;
1575 i++;
1576 updatingLayersAbove = 0;
1577 continue;
1578 } else {
1579 //both failed.start the loop again from here.
1580 if(firstZReverseIndex >= 0) {
1581 i = firstZReverseIndex;
1582 }
1583 break;
1584 }
1585 }
1586 }
1587 }
1588 if(batchCount > maxBatchCount) {
1589 maxBatchCount = batchCount;
1590 maxBatchStart = batchStart;
1591 maxBatchEnd = batchEnd;
1592 fbZOrder = fbZ;
1593 }
1594 }
1595 return fbZOrder;
1596}
1597
1598bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1599 hwc_display_contents_1_t* list) {
1600 /* Idea is to keep as many non-updating(cached) layers in FB and
1601 * send rest of them through MDP. This is done in 2 steps.
1602 * 1. Find the maximum contiguous batch of non-updating layers.
1603 * 2. See if we can improve this batch size for caching by adding
1604 * opaque layers around the batch, if they don't have
1605 * any overlapping with the updating layers in between.
1606 * NEVER mark an updating layer for caching.
1607 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608
1609 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001610 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001611 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301612 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001613
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001614 /* Nothing is cached. No batching needed */
1615 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001616 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001617 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001618
1619 /* No MDP comp layers, try to use other comp modes */
1620 if(mCurrentFrame.mdpCount == 0) {
1621 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001622 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001623
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301624 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001625
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301626 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001628 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001629 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301630 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001631 if(!mCurrentFrame.drop[i]){
1632 //If an unsupported layer is being attempted to
1633 //be pulled out we should fail
1634 if(not isSupportedForMDPComp(ctx, layer)) {
1635 return false;
1636 }
1637 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001638 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001639 }
1640 }
1641
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301642 // update the frame data
1643 mCurrentFrame.fbZ = fbZ;
1644 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001645 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001646 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001647
1648 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301649 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001650
1651 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001652}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001653
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001654void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001655 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001657 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001659 for(int i = 0; i < numAppLayers; i++) {
1660 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001661 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001662 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001663 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001665 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666 }
1667 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001668
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001669 frame.fbCount = fbCount;
1670 frame.mdpCount = frame.layerCount - frame.fbCount
1671 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001672
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001673 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1674 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001675}
1676
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001677// drop other non-AIV layers from external display list.
1678void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001679 hwc_display_contents_1_t* list) {
1680 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1681 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001682 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001683 mCurrentFrame.dropCount++;
1684 mCurrentFrame.drop[i] = true;
1685 }
1686 }
1687 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1688 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1689 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1690 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1691 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1692 mCurrentFrame.dropCount);
1693}
1694
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001695void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001696 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001697 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1698 for(int index = 0;index < nYuvCount; index++){
1699 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1700 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1701
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001702 if(mCurrentFrame.drop[nYuvIndex]) {
1703 continue;
1704 }
1705
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001706 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001707 if(!frame.isFBComposed[nYuvIndex]) {
1708 frame.isFBComposed[nYuvIndex] = true;
1709 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001710 }
1711 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001712 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001713 private_handle_t *hnd = (private_handle_t *)layer->handle;
1714 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001715 frame.isFBComposed[nYuvIndex] = false;
1716 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001717 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001718 }
1719 }
1720 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001721
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001722 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1723 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001724}
1725
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001726void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1727 hwc_display_contents_1_t* list) {
1728 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1729 for(int index = 0;index < nSecureRGBCount; index++){
1730 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1731 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1732
1733 if(!isSecureRGBDoable(ctx, layer)) {
1734 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1735 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1736 mCurrentFrame.fbCount++;
1737 }
1738 } else {
1739 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1740 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1741 mCurrentFrame.fbCount--;
1742 }
1743 }
1744 }
1745
1746 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1747 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1748 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1749 mCurrentFrame.fbCount);
1750}
1751
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001752hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1753 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001754 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001755
1756 /* Update only the region of FB needed for composition */
1757 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1758 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1759 hwc_layer_1_t* layer = &list->hwLayers[i];
1760 hwc_rect_t dst = layer->displayFrame;
1761 fbRect = getUnion(fbRect, dst);
1762 }
1763 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001764 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001765 return fbRect;
1766}
1767
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001768bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1769 hwc_display_contents_1_t* list) {
1770
1771 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001772 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001773 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1774 return false;
1775 }
1776
1777 //Limitations checks
1778 if(!hwLimitationsCheck(ctx, list)) {
1779 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1780 return false;
1781 }
1782
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001783 //Configure framebuffer first if applicable
1784 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001785 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001786 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1787 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001788 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1789 __FUNCTION__);
1790 return false;
1791 }
1792 }
1793
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001794 mCurrentFrame.map();
1795
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001796 if(!allocLayerPipes(ctx, list)) {
1797 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001798 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001799 }
1800
1801 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001802 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001803 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001804 int mdpIndex = mCurrentFrame.layerToMDP[index];
1805 hwc_layer_1_t* layer = &list->hwLayers[index];
1806
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301807 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1808 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1809 mdpNextZOrder++;
1810 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001811 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1812 cur_pipe->zOrder = mdpNextZOrder++;
1813
radhakrishnac9a67412013-09-25 17:40:42 +05301814 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301815 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301816 if(configure4k2kYuv(ctx, layer,
1817 mCurrentFrame.mdpToLayer[mdpIndex])
1818 != 0 ){
1819 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1820 for layer %d",__FUNCTION__, index);
1821 return false;
1822 }
1823 else{
1824 mdpNextZOrder++;
1825 }
1826 continue;
1827 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001828 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1829 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301830 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001831 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001832 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001833 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001834 }
1835
Saurabh Shaha36be922013-12-16 18:18:39 -08001836 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1837 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1838 ,__FUNCTION__, mDpy);
1839 return false;
1840 }
1841
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001842 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001843 return true;
1844}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001845
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001846bool MDPComp::resourceCheck(hwc_context_t* ctx,
1847 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001848 const bool fbUsed = mCurrentFrame.fbCount;
1849 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1850 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1851 return false;
1852 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001853
1854 //Will benefit cases where a video has non-updating background.
1855 if((mDpy > HWC_DISPLAY_PRIMARY) and
1856 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1857 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1858 return false;
1859 }
1860
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001861 // Init rotCount to number of rotate sessions used by other displays
1862 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1863 // Count the number of rotator sessions required for current display
1864 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1865 if(!mCurrentFrame.isFBComposed[index]) {
1866 hwc_layer_1_t* layer = &list->hwLayers[index];
1867 private_handle_t *hnd = (private_handle_t *)layer->handle;
1868 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1869 rotCount++;
1870 }
1871 }
1872 }
1873 // if number of layers to rotate exceeds max rotator sessions, bail out.
1874 if(rotCount > RotMgr::MAX_ROT_SESS) {
1875 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1876 __FUNCTION__, mDpy);
1877 return false;
1878 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001879 return true;
1880}
1881
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301882bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1883 hwc_display_contents_1_t* list) {
1884
1885 //A-family hw limitation:
1886 //If a layer need alpha scaling, MDP can not support.
1887 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1888 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1889 if(!mCurrentFrame.isFBComposed[i] &&
1890 isAlphaScaled( &list->hwLayers[i])) {
1891 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1892 return false;
1893 }
1894 }
1895 }
1896
1897 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1898 //If multiple layers requires downscaling and also they are overlapping
1899 //fall back to GPU since MDSS can not handle it.
1900 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1901 qdutils::MDPVersion::getInstance().is8x26()) {
1902 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1903 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1904 if(!mCurrentFrame.isFBComposed[i] &&
1905 isDownscaleRequired(botLayer)) {
1906 //if layer-i is marked for MDP and needs downscaling
1907 //check if any MDP layer on top of i & overlaps with layer-i
1908 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1909 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1910 if(!mCurrentFrame.isFBComposed[j] &&
1911 isDownscaleRequired(topLayer)) {
1912 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1913 topLayer->displayFrame);
1914 if(isValidRect(r))
1915 return false;
1916 }
1917 }
1918 }
1919 }
1920 }
1921 return true;
1922}
1923
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001924// Checks only if videos or single layer(RGB) is updating
1925// which is used for setting dynamic fps or perf hint for single
1926// layer video playback
1927bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1928 hwc_display_contents_1_t* list) {
1929 bool support = false;
1930 FrameInfo frame;
1931 frame.reset(mCurrentFrame.layerCount);
1932 memset(&frame.drop, 0, sizeof(frame.drop));
1933 frame.dropCount = 0;
1934 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1935 updateLayerCache(ctx, list, frame);
1936 updateYUV(ctx, list, false /*secure only*/, frame);
1937 // There are only updating YUV layers or there is single RGB
1938 // Layer(Youtube)
1939 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1940 (frame.layerCount == 1)) {
1941 support = true;
1942 }
1943 return support;
1944}
1945
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301946void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1947 //For primary display, set the dynamic refreshrate
1948 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1949 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301950 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1951 MDPVersion& mdpHw = MDPVersion::getInstance();
1952 if(sIdleFallBack) {
1953 //Set minimum panel refresh rate during idle timeout
1954 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001955 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301956 //Set the new fresh rate, if there is only one updating YUV layer
1957 //or there is one single RGB layer with this request
1958 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1959 }
1960 setRefreshRate(ctx, mDpy, refreshRate);
1961 }
1962}
1963
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001964int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001965 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001966 char property[PROPERTY_VALUE_MAX];
1967
Raj Kamal4393eaa2014-06-06 13:45:20 +05301968 if(!ctx || !list) {
1969 ALOGE("%s: Invalid context or list",__FUNCTION__);
1970 mCachedFrame.reset();
1971 return -1;
1972 }
1973
1974 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001975 if(mDpy == HWC_DISPLAY_PRIMARY) {
1976 sSimulationFlags = 0;
1977 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1978 int currentFlags = atoi(property);
1979 if(currentFlags != sSimulationFlags) {
1980 sSimulationFlags = currentFlags;
1981 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1982 sSimulationFlags, sSimulationFlags);
1983 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001984 }
1985 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001986 // reset PTOR
1987 if(!mDpy)
1988 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001989
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301990 //reset old data
1991 mCurrentFrame.reset(numLayers);
1992 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1993 mCurrentFrame.dropCount = 0;
1994
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301995 //Do not cache the information for next draw cycle.
1996 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1997 ALOGI("%s: Unsupported layer count for mdp composition",
1998 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001999 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302000#ifdef DYNAMIC_FPS
2001 setDynRefreshRate(ctx, list);
2002#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002003 return -1;
2004 }
2005
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002006 // Detect the start of animation and fall back to GPU only once to cache
2007 // all the layers in FB and display FB content untill animation completes.
2008 if(ctx->listStats[mDpy].isDisplayAnimating) {
2009 mCurrentFrame.needsRedraw = false;
2010 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2011 mCurrentFrame.needsRedraw = true;
2012 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2013 }
2014 setMDPCompLayerFlags(ctx, list);
2015 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302016#ifdef DYNAMIC_FPS
2017 setDynRefreshRate(ctx, list);
2018#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002019 ret = -1;
2020 return ret;
2021 } else {
2022 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2023 }
2024
Saurabh Shahb39f8152013-08-22 10:21:44 -07002025 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002026 if(isFrameDoable(ctx)) {
2027 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002028 // if AIV Video mode is enabled, drop all non AIV layers from the
2029 // external display list.
2030 if(ctx->listStats[mDpy].mAIVVideoMode) {
2031 dropNonAIVLayers(ctx, list);
2032 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002033
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002034 // if tryFullFrame fails, try to push all video and secure RGB layers
2035 // to MDP for composition.
2036 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002037 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302038 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002039 setMDPCompLayerFlags(ctx, list);
2040 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002041 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002042 reset(ctx);
2043 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2044 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002045 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002046 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2047 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002048 }
2049 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302050 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2051 enablePartialUpdateForMDP3) {
2052 generateROI(ctx, list);
2053 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2054 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2055 }
2056 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002057 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2058 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002059 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002060 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002061
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002062 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002063 ALOGD("GEOMETRY change: %d",
2064 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002065 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002066 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002067 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002068 }
2069
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002070#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302071 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002072#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002073 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002074
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002075 mCachedFrame.cacheAll(list);
2076 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002077 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002078}
2079
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002080bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302081
2082 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302083 int mdpIndex = mCurrentFrame.layerToMDP[index];
2084 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2085 info.pipeInfo = new MdpYUVPipeInfo;
2086 info.rot = NULL;
2087 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302088
2089 pipe_info.lIndex = ovutils::OV_INVALID;
2090 pipe_info.rIndex = ovutils::OV_INVALID;
2091
Saurabh Shahc62f3982014-03-05 14:28:26 -08002092 Overlay::PipeSpecs pipeSpecs;
2093 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2094 pipeSpecs.needsScaling = true;
2095 pipeSpecs.dpy = mDpy;
2096 pipeSpecs.fb = false;
2097
2098 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302099 if(pipe_info.lIndex == ovutils::OV_INVALID){
2100 bRet = false;
2101 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2102 __FUNCTION__);
2103 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002104 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302105 if(pipe_info.rIndex == ovutils::OV_INVALID){
2106 bRet = false;
2107 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2108 __FUNCTION__);
2109 }
2110 return bRet;
2111}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002112
2113int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2114 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002115 if (ctx->mPtorInfo.isActive()) {
2116 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002117 if (fd < 0) {
2118 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002119 }
2120 }
2121 return fd;
2122}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002123//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002124
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002125void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302126 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002127 //If 4k2k Yuv layer split is possible, and if
2128 //fbz is above 4k2k layer, increment fb zorder by 1
2129 //as we split 4k2k layer and increment zorder for right half
2130 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002131 if(!ctx)
2132 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002133 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302134 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2135 index++) {
2136 if(!mCurrentFrame.isFBComposed[index]) {
2137 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2138 mdpNextZOrder++;
2139 }
2140 mdpNextZOrder++;
2141 hwc_layer_1_t* layer = &list->hwLayers[index];
2142 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302143 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302144 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2145 mCurrentFrame.fbZ += 1;
2146 mdpNextZOrder++;
2147 //As we split 4kx2k yuv layer and program to 2 VG pipes
2148 //(if available) increase mdpcount by 1.
2149 mCurrentFrame.mdpCount++;
2150 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002151 }
2152 }
2153 }
radhakrishnac9a67412013-09-25 17:40:42 +05302154}
2155
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002156/*
2157 * Configures pipe(s) for MDP composition
2158 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002159int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002160 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002161 MdpPipeInfoNonSplit& mdp_info =
2162 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302163 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002164 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002165 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002166
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002167 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2168 __FUNCTION__, layer, zOrder, dest);
2169
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002170 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002171 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002172}
2173
Saurabh Shah88e4d272013-09-03 13:31:29 -07002174bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002175 hwc_display_contents_1_t* list) {
2176 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002177
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002178 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002179
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002180 hwc_layer_1_t* layer = &list->hwLayers[index];
2181 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302182 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002183 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302184 continue;
2185 }
2186 }
2187
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002188 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002189 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002190 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002191 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002192 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002193
Saurabh Shahc62f3982014-03-05 14:28:26 -08002194 Overlay::PipeSpecs pipeSpecs;
2195 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2196 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2197 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2198 (qdutils::MDPVersion::getInstance().is8x26() and
2199 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2200 pipeSpecs.dpy = mDpy;
2201 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002202 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002203
Saurabh Shahc62f3982014-03-05 14:28:26 -08002204 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2205
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002206 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002207 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002208 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002209 }
2210 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002211 return true;
2212}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002213
radhakrishnac9a67412013-09-25 17:40:42 +05302214int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2215 PipeLayerPair& PipeLayerPair) {
2216 MdpYUVPipeInfo& mdp_info =
2217 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2218 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302219 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302220 eDest lDest = mdp_info.lIndex;
2221 eDest rDest = mdp_info.rIndex;
2222
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002223 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302224 lDest, rDest, &PipeLayerPair.rot);
2225}
2226
Saurabh Shah88e4d272013-09-03 13:31:29 -07002227bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002228
Raj Kamal4393eaa2014-06-06 13:45:20 +05302229 if(!isEnabled() or !mModeOn) {
2230 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302231 return true;
2232 }
2233
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002234 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002235 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002236 sHandleTimeout = true;
2237 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002238
2239 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002240 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002241
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002242 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2243 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002244 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002245 if(mCurrentFrame.isFBComposed[i]) continue;
2246
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002247 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002248 private_handle_t *hnd = (private_handle_t *)layer->handle;
2249 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002250 if (!(layer->flags & HWC_COLOR_FILL)) {
2251 ALOGE("%s handle null", __FUNCTION__);
2252 return false;
2253 }
2254 // No PLAY for Color layer
2255 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2256 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002257 }
2258
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002259 int mdpIndex = mCurrentFrame.layerToMDP[i];
2260
Raj Kamal389d6e32014-08-04 14:43:24 +05302261 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302262 {
2263 MdpYUVPipeInfo& pipe_info =
2264 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2265 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2266 ovutils::eDest indexL = pipe_info.lIndex;
2267 ovutils::eDest indexR = pipe_info.rIndex;
2268 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302269 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302270 if(rot) {
2271 rot->queueBuffer(fd, offset);
2272 fd = rot->getDstMemId();
2273 offset = rot->getDstOffset();
2274 }
2275 if(indexL != ovutils::OV_INVALID) {
2276 ovutils::eDest destL = (ovutils::eDest)indexL;
2277 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2278 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2279 if (!ov.queueBuffer(fd, offset, destL)) {
2280 ALOGE("%s: queueBuffer failed for display:%d",
2281 __FUNCTION__, mDpy);
2282 return false;
2283 }
2284 }
2285
2286 if(indexR != ovutils::OV_INVALID) {
2287 ovutils::eDest destR = (ovutils::eDest)indexR;
2288 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2289 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2290 if (!ov.queueBuffer(fd, offset, destR)) {
2291 ALOGE("%s: queueBuffer failed for display:%d",
2292 __FUNCTION__, mDpy);
2293 return false;
2294 }
2295 }
2296 }
2297 else{
2298 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002299 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302300 ovutils::eDest dest = pipe_info.index;
2301 if(dest == ovutils::OV_INVALID) {
2302 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002303 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302304 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002305
radhakrishnac9a67412013-09-25 17:40:42 +05302306 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2307 continue;
2308 }
2309
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002310 int fd = hnd->fd;
2311 uint32_t offset = (uint32_t)hnd->offset;
2312 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2313 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002314 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002315 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002316 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002317 }
2318
radhakrishnac9a67412013-09-25 17:40:42 +05302319 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2320 using pipe: %d", __FUNCTION__, layer,
2321 hnd, dest );
2322
radhakrishnac9a67412013-09-25 17:40:42 +05302323 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2324 if(rot) {
2325 if(!rot->queueBuffer(fd, offset))
2326 return false;
2327 fd = rot->getDstMemId();
2328 offset = rot->getDstOffset();
2329 }
2330
2331 if (!ov.queueBuffer(fd, offset, dest)) {
2332 ALOGE("%s: queueBuffer failed for display:%d ",
2333 __FUNCTION__, mDpy);
2334 return false;
2335 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002336 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002337
2338 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002339 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002340 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002341}
2342
Saurabh Shah88e4d272013-09-03 13:31:29 -07002343//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002344
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002345void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302346 hwc_display_contents_1_t* list){
2347 //if 4kx2k yuv layer is totally present in either in left half
2348 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302349 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302350 if(mCurrentFrame.fbZ >= 0) {
2351 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2352 index++) {
2353 if(!mCurrentFrame.isFBComposed[index]) {
2354 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2355 mdpNextZOrder++;
2356 }
2357 mdpNextZOrder++;
2358 hwc_layer_1_t* layer = &list->hwLayers[index];
2359 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302360 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302361 hwc_rect_t dst = layer->displayFrame;
2362 if((dst.left > lSplit) || (dst.right < lSplit)) {
2363 mCurrentFrame.mdpCount += 1;
2364 }
2365 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2366 mCurrentFrame.fbZ += 1;
2367 mdpNextZOrder++;
2368 }
2369 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002370 }
radhakrishnac9a67412013-09-25 17:40:42 +05302371 }
2372}
2373
Saurabh Shah88e4d272013-09-03 13:31:29 -07002374bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002375 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002376
Saurabh Shahc62f3982014-03-05 14:28:26 -08002377 const int lSplit = getLeftSplit(ctx, mDpy);
2378 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002379 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002380 pipe_info.lIndex = ovutils::OV_INVALID;
2381 pipe_info.rIndex = ovutils::OV_INVALID;
2382
Saurabh Shahc62f3982014-03-05 14:28:26 -08002383 Overlay::PipeSpecs pipeSpecs;
2384 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2385 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2386 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2387 pipeSpecs.dpy = mDpy;
2388 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2389 pipeSpecs.fb = false;
2390
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002391 // Acquire pipe only for the updating half
2392 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2393 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2394
2395 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002396 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002397 if(pipe_info.lIndex == ovutils::OV_INVALID)
2398 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002399 }
2400
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002401 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002402 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2403 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002404 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002405 return false;
2406 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002407
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002408 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002409}
2410
Saurabh Shah88e4d272013-09-03 13:31:29 -07002411bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002412 hwc_display_contents_1_t* list) {
2413 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002414
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002415 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002416
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002417 hwc_layer_1_t* layer = &list->hwLayers[index];
2418 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302419 hwc_rect_t dst = layer->displayFrame;
2420 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302421 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302422 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002423 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302424 continue;
2425 }
2426 }
2427 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002428 int mdpIndex = mCurrentFrame.layerToMDP[index];
2429 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002430 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002431 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002432 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002433
Saurabh Shahc62f3982014-03-05 14:28:26 -08002434 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2435 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2436 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002437 return false;
2438 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002439 }
2440 return true;
2441}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002442
radhakrishnac9a67412013-09-25 17:40:42 +05302443int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2444 PipeLayerPair& PipeLayerPair) {
2445 const int lSplit = getLeftSplit(ctx, mDpy);
2446 hwc_rect_t dst = layer->displayFrame;
2447 if((dst.left > lSplit)||(dst.right < lSplit)){
2448 MdpYUVPipeInfo& mdp_info =
2449 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2450 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302451 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302452 eDest lDest = mdp_info.lIndex;
2453 eDest rDest = mdp_info.rIndex;
2454
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002455 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302456 lDest, rDest, &PipeLayerPair.rot);
2457 }
2458 else{
2459 return configure(ctx, layer, PipeLayerPair);
2460 }
2461}
2462
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002463/*
2464 * Configures pipe(s) for MDP composition
2465 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002466int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002467 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002468 MdpPipeInfoSplit& mdp_info =
2469 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002470 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302471 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002472 eDest lDest = mdp_info.lIndex;
2473 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002474
2475 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002476 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002477
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002478 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002479 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002480}
2481
Saurabh Shah88e4d272013-09-03 13:31:29 -07002482bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002483
Raj Kamal4393eaa2014-06-06 13:45:20 +05302484 if(!isEnabled() or !mModeOn) {
2485 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302486 return true;
2487 }
2488
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002489 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002490 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002491 sHandleTimeout = true;
2492 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002493
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002494 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002495 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002496
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002497 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2498 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002499 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002500 if(mCurrentFrame.isFBComposed[i]) continue;
2501
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002502 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002503 private_handle_t *hnd = (private_handle_t *)layer->handle;
2504 if(!hnd) {
2505 ALOGE("%s handle null", __FUNCTION__);
2506 return false;
2507 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002508
2509 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2510 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002511 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002512
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002513 int mdpIndex = mCurrentFrame.layerToMDP[i];
2514
Raj Kamal389d6e32014-08-04 14:43:24 +05302515 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302516 {
2517 MdpYUVPipeInfo& pipe_info =
2518 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2519 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2520 ovutils::eDest indexL = pipe_info.lIndex;
2521 ovutils::eDest indexR = pipe_info.rIndex;
2522 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302523 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302524 if(rot) {
2525 rot->queueBuffer(fd, offset);
2526 fd = rot->getDstMemId();
2527 offset = rot->getDstOffset();
2528 }
2529 if(indexL != ovutils::OV_INVALID) {
2530 ovutils::eDest destL = (ovutils::eDest)indexL;
2531 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2532 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2533 if (!ov.queueBuffer(fd, offset, destL)) {
2534 ALOGE("%s: queueBuffer failed for display:%d",
2535 __FUNCTION__, mDpy);
2536 return false;
2537 }
2538 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002539
radhakrishnac9a67412013-09-25 17:40:42 +05302540 if(indexR != ovutils::OV_INVALID) {
2541 ovutils::eDest destR = (ovutils::eDest)indexR;
2542 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2543 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2544 if (!ov.queueBuffer(fd, offset, destR)) {
2545 ALOGE("%s: queueBuffer failed for display:%d",
2546 __FUNCTION__, mDpy);
2547 return false;
2548 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002549 }
2550 }
radhakrishnac9a67412013-09-25 17:40:42 +05302551 else{
2552 MdpPipeInfoSplit& pipe_info =
2553 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2554 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002555
radhakrishnac9a67412013-09-25 17:40:42 +05302556 ovutils::eDest indexL = pipe_info.lIndex;
2557 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002558
radhakrishnac9a67412013-09-25 17:40:42 +05302559 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002560 uint32_t offset = (uint32_t)hnd->offset;
2561 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2562 if (!mDpy && (index != -1)) {
2563 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2564 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002565 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002566 }
radhakrishnac9a67412013-09-25 17:40:42 +05302567
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002568 if(ctx->mAD->draw(ctx, fd, offset)) {
2569 fd = ctx->mAD->getDstFd();
2570 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002571 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002572
radhakrishnac9a67412013-09-25 17:40:42 +05302573 if(rot) {
2574 rot->queueBuffer(fd, offset);
2575 fd = rot->getDstMemId();
2576 offset = rot->getDstOffset();
2577 }
2578
2579 //************* play left mixer **********
2580 if(indexL != ovutils::OV_INVALID) {
2581 ovutils::eDest destL = (ovutils::eDest)indexL;
2582 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2583 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2584 if (!ov.queueBuffer(fd, offset, destL)) {
2585 ALOGE("%s: queueBuffer failed for left mixer",
2586 __FUNCTION__);
2587 return false;
2588 }
2589 }
2590
2591 //************* play right mixer **********
2592 if(indexR != ovutils::OV_INVALID) {
2593 ovutils::eDest destR = (ovutils::eDest)indexR;
2594 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2595 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2596 if (!ov.queueBuffer(fd, offset, destR)) {
2597 ALOGE("%s: queueBuffer failed for right mixer",
2598 __FUNCTION__);
2599 return false;
2600 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002601 }
2602 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002603
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002604 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2605 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002606
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002607 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002608}
Saurabh Shahab47c692014-02-12 18:45:57 -08002609
2610//================MDPCompSrcSplit==============================================
2611bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002612 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002613 private_handle_t *hnd = (private_handle_t *)layer->handle;
2614 hwc_rect_t dst = layer->displayFrame;
2615 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2616 pipe_info.lIndex = ovutils::OV_INVALID;
2617 pipe_info.rIndex = ovutils::OV_INVALID;
2618
2619 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2620 //should have a higher priority than the right one. Pipe priorities are
2621 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002622
Saurabh Shahc62f3982014-03-05 14:28:26 -08002623 Overlay::PipeSpecs pipeSpecs;
2624 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2625 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2626 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2627 pipeSpecs.dpy = mDpy;
2628 pipeSpecs.fb = false;
2629
Saurabh Shahab47c692014-02-12 18:45:57 -08002630 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002631 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002632 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002633 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002634 }
2635
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002636 /* Use 2 pipes IF
2637 a) Layer's crop width is > 2048 or
2638 b) Layer's dest width > 2048 or
2639 c) On primary, driver has indicated with caps to split always. This is
2640 based on an empirically derived value of panel height. Applied only
2641 if the layer's width is > mixer's width
2642 */
2643
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302644 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002645 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302646 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002647 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2648 const uint32_t dstWidth = dst.right - dst.left;
2649 const uint32_t dstHeight = dst.bottom - dst.top;
2650 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002651 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002652 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2653 crop.bottom - crop.top;
2654 //Approximation to actual clock, ignoring the common factors in pipe and
2655 //mixer cases like line_time
2656 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2657 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002658
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002659 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2660 //pipe line length, we are still using 2 pipes. This is fine just because
2661 //this is source split where destination doesn't matter. Evaluate later to
2662 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002663 if(dstWidth > mdpHw.getMaxPipeWidth() or
2664 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002665 (primarySplitAlways and
2666 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002667 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002668 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002669 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002670 }
2671
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002672 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2673 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002674 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002675 }
2676 }
2677
2678 return true;
2679}
2680
Saurabh Shahab47c692014-02-12 18:45:57 -08002681int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2682 PipeLayerPair& PipeLayerPair) {
2683 private_handle_t *hnd = (private_handle_t *)layer->handle;
2684 if(!hnd) {
2685 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2686 return -1;
2687 }
2688 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2689 MdpPipeInfoSplit& mdp_info =
2690 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2691 Rotator **rot = &PipeLayerPair.rot;
2692 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002693 eDest lDest = mdp_info.lIndex;
2694 eDest rDest = mdp_info.rIndex;
2695 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2696 hwc_rect_t dst = layer->displayFrame;
2697 int transform = layer->transform;
2698 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002699 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002700 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002701 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2702
2703 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2704 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2705
2706 // Handle R/B swap
2707 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2708 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2709 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2710 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2711 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2712 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002713 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002714 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2715 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002716 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002717 /* Calculate the external display position based on MDP downscale,
2718 ActionSafe, and extorientation features. */
2719 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002720
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002721 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302722 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002723 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002724
2725 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2726 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002727 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002728 }
2729
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002730 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002731 (*rot) = ctx->mRotMgr->getNext();
2732 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002733 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002734 //If the video is using a single pipe, enable BWC
2735 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002736 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2737 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002738 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002739 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002740 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002741 ALOGE("%s: configRotator failed!", __FUNCTION__);
2742 return -1;
2743 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002744 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002745 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002746 }
2747
2748 //If 2 pipes being used, divide layer into half, crop and dst
2749 hwc_rect_t cropL = crop;
2750 hwc_rect_t cropR = crop;
2751 hwc_rect_t dstL = dst;
2752 hwc_rect_t dstR = dst;
2753 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2754 cropL.right = (crop.right + crop.left) / 2;
2755 cropR.left = cropL.right;
2756 sanitizeSourceCrop(cropL, cropR, hnd);
2757
Saurabh Shahb729b192014-08-15 18:04:24 -07002758 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002759 //Swap crops on H flip since 2 pipes are being used
2760 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2761 hwc_rect_t tmp = cropL;
2762 cropL = cropR;
2763 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002764 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002765 }
2766
Saurabh Shahb729b192014-08-15 18:04:24 -07002767 //cropSwap trick: If the src and dst widths are both odd, let us say
2768 //2507, then splitting both into half would cause left width to be 1253
2769 //and right 1254. If crop is swapped because of H flip, this will cause
2770 //left crop width to be 1254, whereas left dst width remains 1253, thus
2771 //inducing a scaling that is unaccounted for. To overcome that we add 1
2772 //to the dst width if there is a cropSwap. So if the original width was
2773 //2507, the left dst width will be 1254. Even if the original width was
2774 //even for ex: 2508, the left dst width will still remain 1254.
2775 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002776 dstR.left = dstL.right;
2777 }
2778
2779 //For the mdp, since either we are pre-rotating or MDP does flips
2780 orient = OVERLAY_TRANSFORM_0;
2781 transform = 0;
2782
2783 //configure left pipe
2784 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002785 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002786 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2787 (ovutils::eBlending) getBlending(layer->blending));
2788
2789 if(configMdp(ctx->mOverlay, pargL, orient,
2790 cropL, dstL, metadata, lDest) < 0) {
2791 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2792 return -1;
2793 }
2794 }
2795
2796 //configure right pipe
2797 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002798 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002799 static_cast<eRotFlags>(rotFlags),
2800 layer->planeAlpha,
2801 (ovutils::eBlending) getBlending(layer->blending));
2802 if(configMdp(ctx->mOverlay, pargR, orient,
2803 cropR, dstR, metadata, rDest) < 0) {
2804 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2805 return -1;
2806 }
2807 }
2808
2809 return 0;
2810}
2811
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002812bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2813 Locker::Autolock _l(ctx->mDrawLock);
2814 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2815 char path[MAX_SYSFS_FILE_PATH];
2816 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2817 int fd = open(path, O_RDONLY);
2818 if(fd < 0) {
2819 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2820 return -1;
2821 }
2822 char value[4];
2823 ssize_t size_read = read(fd, value, sizeof(value)-1);
2824 if(size_read <= 0) {
2825 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2826 close(fd);
2827 return -1;
2828 }
2829 close(fd);
2830 value[size_read] = '\0';
2831 return atoi(value);
2832}
2833
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002834int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2835 Locker::Autolock _l(ctx->mDrawLock);
2836 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2837 char path[MAX_SYSFS_FILE_PATH];
2838 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2839 int fd = open(path, O_WRONLY);
2840 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002841 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002842 return -1;
2843 }
2844 char value[4];
2845 snprintf(value, sizeof(value), "%d", (int)enable);
2846 ssize_t ret = write(fd, value, strlen(value));
2847 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002848 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002849 close(fd);
2850 return -1;
2851 }
2852 close(fd);
2853 sIsPartialUpdateActive = enable;
2854 return 0;
2855}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002856
2857bool MDPComp::loadPerfLib() {
2858 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2859 bool success = false;
2860 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2861 ALOGE("vendor library not set in ro.vendor.extension_library");
2862 return false;
2863 }
2864
2865 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
2866 if(sLibPerfHint) {
2867 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
2868 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
2869 if (!sPerfLockAcquire || !sPerfLockRelease) {
2870 ALOGE("Failed to load symbols for perfLock");
2871 dlclose(sLibPerfHint);
2872 sLibPerfHint = NULL;
2873 return false;
2874 }
2875 success = true;
2876 ALOGI("Successfully Loaded perf hint API's");
2877 } else {
2878 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
2879 }
2880 return success;
2881}
2882
2883void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2884 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
2885 return;
2886 }
2887 static int count = sPerfHintWindow;
2888 static int perflockFlag = 0;
2889
2890 /* Send hint to mpctl when single layer is updated
2891 * for a successful number of windows. Hint release
2892 * happens immediately upon multiple layer update.
2893 */
2894 if (onlyVideosUpdating(ctx, list)) {
2895 if(count) {
2896 count--;
2897 }
2898 } else {
2899 if (perflockFlag) {
2900 perflockFlag = 0;
2901 sPerfLockRelease(sPerfLockHandle);
2902 }
2903 count = sPerfHintWindow;
2904 }
2905 if (count == 0 && !perflockFlag) {
2906 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
2907 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
2908 &perfHint, sizeof(perfHint)/sizeof(int));
2909 if(sPerfLockHandle < 0) {
2910 ALOGE("Perf Lock Acquire Failed");
2911 } else {
2912 perflockFlag = 1;
2913 }
2914 }
2915}
2916
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002917}; //namespace
2918