blob: d50fa1d9d07b3e54088a792e756248d996411e84 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080022#include <dlfcn.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070023#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070030#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080031
Saurabh Shah85234ec2013-04-12 17:09:00 -070032using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070033using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080034using namespace overlay::utils;
35namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037namespace qhwc {
38
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080039//==============MDPComp========================================================
40
Saurabh Shah59562ff2014-09-30 16:13:12 -070041IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080043bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070044bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050045bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070046bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070047int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070048int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053049bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070050bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080051int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053052bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070053bool MDPComp::sIsPartialUpdateActive = true;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080054void *MDPComp::sLibPerfHint = NULL;
55int MDPComp::sPerfLockHandle = 0;
56int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
57int (*MDPComp::sPerfLockRelease)(int value) = NULL;
58int MDPComp::sPerfHintWindow = -1;
59
Saurabh Shah88e4d272013-09-03 13:31:29 -070060MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070061 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
62 sSrcSplitEnabled = true;
63 return new MDPCompSrcSplit(dpy);
64 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070065 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080066 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070067 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080068}
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070MDPComp::MDPComp(int dpy):mDpy(dpy){};
71
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070072void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080073{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070074 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
75 return;
76
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080077 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070078 (mDpy == 0) ? "\"PRIMARY\"" :
79 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070080 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
81 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080082 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
83 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
84 (mCurrentFrame.needsRedraw? "YES" : "NO"),
85 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070086 if(isDisplaySplit(ctx, mDpy)) {
87 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
88 "Right: [%d, %d, %d, %d] \n",
89 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
90 ctx->listStats[mDpy].lRoi.right,
91 ctx->listStats[mDpy].lRoi.bottom,
92 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
93 ctx->listStats[mDpy].rRoi.right,
94 ctx->listStats[mDpy].rRoi.bottom);
95 } else {
96 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
97 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
98 ctx->listStats[mDpy].lRoi.right,
99 ctx->listStats[mDpy].lRoi.bottom);
100 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 dumpsys_log(buf," --------------------------------------------- \n");
102 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
103 dumpsys_log(buf," --------------------------------------------- \n");
104 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
105 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
106 index,
107 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700108 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800109 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700110 (mCurrentFrame.drop[index] ? "DROP" :
111 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800112 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
113 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
114 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115}
116
117bool MDPComp::init(hwc_context_t *ctx) {
118
119 if(!ctx) {
120 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
121 return false;
122 }
123
Saurabh Shah59562ff2014-09-30 16:13:12 -0700124 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800125
126 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530127 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
128 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800131 sEnabled = true;
132 }
133
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700134 sEnableMixedMode = true;
135 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
136 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
137 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
138 sEnableMixedMode = false;
139 }
140
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700141 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
142
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800143 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700144 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700145 int val = atoi(property);
146 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700147 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800148 }
149
Saurabh Shahacec8e42014-11-25 11:07:04 -0800150 /* Maximum layers allowed to use MDP on secondary panels. If property
151 * doesn't exist, default to 1. Using the property it can be set to 0 or
152 * more.
153 */
154 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
155 int val = atoi(property);
156 sMaxSecLayers = (val >= 0) ? val : 1;
157 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
158 }
159
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700161 sIdleInvalidator = IdleInvalidator::getInstance();
162 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
163 delete sIdleInvalidator;
164 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400165 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800166 }
radhakrishnac9a67412013-09-25 17:40:42 +0530167
Saurabh Shah7c727642014-06-02 15:47:14 -0700168 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700169 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700170 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
171 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
172 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530173 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530174 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700175
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530176 bool defaultPTOR = false;
177 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
178 //8x16 and 8x39 targets by default
179 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
180 (qdutils::MDPVersion::getInstance().is8x16() ||
181 qdutils::MDPVersion::getInstance().is8x39())) {
182 defaultPTOR = true;
183 }
184
185 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
186 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700187 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
188 HWC_DISPLAY_PRIMARY);
189 }
190
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530191 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
192 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
193 enablePartialUpdateForMDP3 = true;
194 }
195
196 if(!enablePartialUpdateForMDP3 &&
197 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
198 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
199 enablePartialUpdateForMDP3 = true;
200 }
201
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800202 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
203
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800204 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
205 int val = atoi(property);
206 if(val > 0 && loadPerfLib()) {
207 sPerfHintWindow = val;
208 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
209 }
210 }
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212 return true;
213}
214
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800215void MDPComp::reset(hwc_context_t *ctx) {
216 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700217 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800218 ctx->mOverlay->clear(mDpy);
219 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700220}
221
Raj Kamal4393eaa2014-06-06 13:45:20 +0530222void MDPComp::reset() {
223 sHandleTimeout = false;
224 mModeOn = false;
225}
226
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227void MDPComp::timeout_handler(void *udata) {
228 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
229
230 if(!ctx) {
231 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
232 return;
233 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530234
235 ctx->mDrawLock.lock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800236 // Handle timeout event only if the previous composition is MDP or MIXED.
237 if(!sHandleTimeout) {
238 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530239 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800240 return;
241 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700242 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700243 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530244 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700245 return;
246 }
247 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530248 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700249 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700250 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700251}
252
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700253void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
254 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800255 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700256 if(value > maxSupported) {
257 ALOGW("%s: Input exceeds max value supported. Setting to"
258 "max value: %d", __FUNCTION__, maxSupported);
259 }
260 sMaxPipesPerMixer = min(value, maxSupported);
261}
262
Saurabh Shah59562ff2014-09-30 16:13:12 -0700263void MDPComp::setIdleTimeout(const uint32_t& timeout) {
264 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
265
266 if(sIdleInvalidator) {
267 if(timeout <= ONE_REFRESH_PERIOD_MS) {
268 //If the specified timeout is < 1 draw cycle worth, "virtually"
269 //disable idle timeout. The ideal way for clients to disable
270 //timeout is to set it to 0
271 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
272 ALOGI("Disabled idle timeout");
273 return;
274 }
275 sIdleInvalidator->setIdleTimeout(timeout);
276 ALOGI("Idle timeout set to %u", timeout);
277 } else {
278 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
279 }
280}
281
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800282void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283 hwc_display_contents_1_t* list) {
284 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800285
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800287 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800288 if(!mCurrentFrame.isFBComposed[index]) {
289 layerProp[index].mFlags |= HWC_MDPCOMP;
290 layer->compositionType = HWC_OVERLAY;
291 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800292 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700293 /* Drop the layer when its already present in FB OR when it lies
294 * outside frame's ROI */
295 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700297 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800298 }
299 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700300}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500301
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800302void MDPComp::setRedraw(hwc_context_t *ctx,
303 hwc_display_contents_1_t* list) {
304 mCurrentFrame.needsRedraw = false;
305 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
306 (list->flags & HWC_GEOMETRY_CHANGED) ||
307 isSkipPresent(ctx, mDpy)) {
308 mCurrentFrame.needsRedraw = true;
309 }
310}
311
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800312MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700313 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700314 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316
Saurabh Shahaa236822013-04-24 18:07:26 -0700317void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700318 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800319 if(mdpToLayer[i].pipeInfo) {
320 delete mdpToLayer[i].pipeInfo;
321 mdpToLayer[i].pipeInfo = NULL;
322 //We dont own the rotator
323 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800324 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800325 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800326
327 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
328 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700329 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330
Saurabh Shahaa236822013-04-24 18:07:26 -0700331 layerCount = numLayers;
332 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800333 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700334 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800335 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336}
337
Saurabh Shahaa236822013-04-24 18:07:26 -0700338void MDPComp::FrameInfo::map() {
339 // populate layer and MDP maps
340 int mdpIdx = 0;
341 for(int idx = 0; idx < layerCount; idx++) {
342 if(!isFBComposed[idx]) {
343 mdpToLayer[mdpIdx].listIndex = idx;
344 layerToMDP[idx] = mdpIdx++;
345 }
346 }
347}
348
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800349MDPComp::LayerCache::LayerCache() {
350 reset();
351}
352
353void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700354 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530355 memset(&isFBComposed, true, sizeof(isFBComposed));
356 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700358}
359
360void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530361 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700362 for(int i = 0; i < numAppLayers; i++) {
363 hnd[i] = list->hwLayers[i].handle;
364 }
365}
366
367void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700368 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530369 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
370 memcpy(&drop, &curFrame.drop, sizeof(drop));
371}
372
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800373bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
374 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530375 if(layerCount != curFrame.layerCount)
376 return false;
377 for(int i = 0; i < curFrame.layerCount; i++) {
378 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
379 (curFrame.drop[i] != drop[i])) {
380 return false;
381 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800382 if(curFrame.isFBComposed[i] &&
383 (hnd[i] != list->hwLayers[i].handle)){
384 return false;
385 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530386 }
387 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800388}
389
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700390bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
391 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800392 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530393 (not isValidDimension(ctx,layer)) ||
394 isSkipLayer(layer)) {
395 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700396 return false;
397 }
398 return true;
399}
400
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530401bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800402 private_handle_t *hnd = (private_handle_t *)layer->handle;
403
404 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700405 if (layer->flags & HWC_COLOR_FILL) {
406 // Color layer
407 return true;
408 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700409 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return false;
411 }
412
Naseer Ahmede850a802013-09-06 13:12:52 -0400413 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400414 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400415 return false;
416
Saurabh Shah62e1d732013-09-17 10:44:05 -0700417 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700418 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700419 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700420 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
421 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700422 int dst_w = dst.right - dst.left;
423 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800424 float w_scale = ((float)crop_w / (float)dst_w);
425 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530426 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800428 /* Workaround for MDP HW limitation in DSI command mode panels where
429 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
430 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530431 * There also is a HW limilation in MDP, minimum block size is 2x2
432 * Fallback to GPU if height is less than 2.
433 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700434 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800435 return false;
436
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800437 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530438 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800439 const float w_dscale = w_scale;
440 const float h_dscale = h_scale;
441
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800442 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700443
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530444 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700445 /* On targets that doesnt support Decimation (eg.,8x26)
446 * maximum downscale support is overlay pipe downscale.
447 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800448 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530449 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700450 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800451 return false;
452 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700453 // Decimation on macrotile format layers is not supported.
454 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530455 /* Bail out if
456 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700457 * 2. exceeds maximum downscale limit
458 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800459 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530460 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700461 w_dscale > maxMDPDownscale ||
462 h_dscale > maxMDPDownscale) {
463 return false;
464 }
465 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800466 return false;
467 }
468 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700469 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700470 return false;
471 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700472 }
473
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800474 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530475 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800476 const float w_uscale = 1.0f / w_scale;
477 const float h_uscale = 1.0f / h_scale;
478
479 if(w_uscale > upscale || h_uscale > upscale)
480 return false;
481 }
482
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800483 return true;
484}
485
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800486bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700487 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800488
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800489 if(!isEnabled()) {
490 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700491 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530492 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530493 qdutils::MDPVersion::getInstance().is8x16() ||
494 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800495 ctx->mVideoTransFlag &&
496 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700497 //1 Padding round to shift pipes across mixers
498 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
499 __FUNCTION__);
500 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700501 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
502 /* TODO: freeing up all the resources only for the targets having total
503 number of pipes < 8. Need to analyze number of VIG pipes used
504 for primary in previous draw cycle and accordingly decide
505 whether to fall back to full GPU comp or video only comp
506 */
507 if(isSecondaryConfiguring(ctx)) {
508 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
509 __FUNCTION__);
510 ret = false;
511 } else if(ctx->isPaddingRound) {
512 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
513 __FUNCTION__,mDpy);
514 ret = false;
515 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800516 } else if (ctx->isDMAStateChanging) {
517 // Bail out if a padding round has been invoked in order to switch DMA
518 // state to block mode. We need this to cater for the case when a layer
519 // requires rotation in the current frame.
520 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
521 __FUNCTION__);
522 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700523 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800524
Saurabh Shahaa236822013-04-24 18:07:26 -0700525 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800526}
527
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800528void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
529 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800530 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800531 dst = getIntersection(dst, roi);
532 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533}
534
535/* 1) Identify layers that are not visible or lying outside the updating ROI and
536 * drop them from composition.
537 * 2) If we have a scaling layer which needs cropping against generated
538 * ROI, reset ROI to full resolution. */
539bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
540 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700541 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800542 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800543
544 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800545 if(!isValidRect(visibleRect)) {
546 mCurrentFrame.drop[i] = true;
547 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800548 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800549 }
550
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700551 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700552 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800553 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700554
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700555 if(!isValidRect(res)) {
556 mCurrentFrame.drop[i] = true;
557 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800558 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700559 /* Reset frame ROI when any layer which needs scaling also needs ROI
560 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800561 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800562 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700563 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
564 mCurrentFrame.dropCount = 0;
565 return false;
566 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800567
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800568 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530569 if (layer->blending == HWC_BLENDING_NONE &&
570 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800571 visibleRect = deductRect(visibleRect, res);
572 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700573 }
574 return true;
575}
576
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
578 * are updating. If DirtyRegion is applicable, calculate it by accounting all
579 * the changing layer's dirtyRegion. */
580void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
581 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700582 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800583 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700584 return;
585
586 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800587 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
588 (int)ctx->dpyAttr[mDpy].yres};
589
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700590 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800591 hwc_layer_1_t* layer = &list->hwLayers[index];
592 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800593 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700594 hwc_rect_t dst = layer->displayFrame;
595 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800596
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800597#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530598 if(!needsScaling(layer) && !layer->transform &&
599 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700600 {
601 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
602 int x_off = dst.left - src.left;
603 int y_off = dst.top - src.top;
604 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
605 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800606#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800607
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800608 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700609 }
610 }
611
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800612 /* No layer is updating. Still SF wants a refresh.*/
613 if(!isValidRect(roi))
614 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800615
616 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800617 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800618
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800619 ctx->listStats[mDpy].lRoi = roi;
620 if(!validateAndApplyROI(ctx, list))
621 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700622
623 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800624 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
625 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
626}
627
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800628void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
629 hwc_rect &dst) {
630 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
631 ctx->listStats[mDpy].rRoi);
632 hwc_rect tmpDst = getIntersection(dst, roi);
633 if(!isSameRect(dst, tmpDst)) {
634 crop.left = crop.left + (tmpDst.left - dst.left);
635 crop.top = crop.top + (tmpDst.top - dst.top);
636 crop.right = crop.left + (tmpDst.right - tmpDst.left);
637 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
638 dst = tmpDst;
639 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800640}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800641
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800642/* 1) Identify layers that are not visible or lying outside BOTH the updating
643 * ROI's and drop them from composition. If a layer is spanning across both
644 * the halves of the screen but needed by only ROI, the non-contributing
645 * half will not be programmed for MDP.
646 * 2) If we have a scaling layer which needs cropping against generated
647 * ROI, reset ROI to full resolution. */
648bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
649 hwc_display_contents_1_t* list) {
650
651 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
652
653 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
654 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
655
656 for(int i = numAppLayers - 1; i >= 0; i--){
657 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
658 {
659 mCurrentFrame.drop[i] = true;
660 mCurrentFrame.dropCount++;
661 continue;
662 }
663
664 const hwc_layer_1_t* layer = &list->hwLayers[i];
665 hwc_rect_t dstRect = layer->displayFrame;
666
667 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
668 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
669 hwc_rect_t res = getUnion(l_res, r_res);
670
671 if(!isValidRect(l_res) && !isValidRect(r_res)) {
672 mCurrentFrame.drop[i] = true;
673 mCurrentFrame.dropCount++;
674 } else {
675 /* Reset frame ROI when any layer which needs scaling also needs ROI
676 * cropping */
677 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
678 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
679 mCurrentFrame.dropCount = 0;
680 return false;
681 }
682
radhakrishna4efbdd62014-11-03 13:19:27 +0530683 if (layer->blending == HWC_BLENDING_NONE &&
684 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800685 visibleRectL = deductRect(visibleRectL, l_res);
686 visibleRectR = deductRect(visibleRectR, r_res);
687 }
688 }
689 }
690 return true;
691}
692/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
693 * are updating. If DirtyRegion is applicable, calculate it by accounting all
694 * the changing layer's dirtyRegion. */
695void MDPCompSplit::generateROI(hwc_context_t *ctx,
696 hwc_display_contents_1_t* list) {
697 if(!canPartialUpdate(ctx, list))
698 return;
699
700 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
701 int lSplit = getLeftSplit(ctx, mDpy);
702
703 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
704 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
705
706 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
707 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
708
709 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
710 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
711
712 for(int index = 0; index < numAppLayers; index++ ) {
713 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800714 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800715 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800716 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700717 hwc_rect_t dst = layer->displayFrame;
718 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800719
720#ifdef QCOM_BSP
721 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700722 {
723 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
724 int x_off = dst.left - src.left;
725 int y_off = dst.top - src.top;
726 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
727 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800728#endif
729
730 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
731 if(isValidRect(l_dst))
732 l_roi = getUnion(l_roi, l_dst);
733
734 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
735 if(isValidRect(r_dst))
736 r_roi = getUnion(r_roi, r_dst);
737 }
738 }
739
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700740 /* For panels that cannot accept commands in both the interfaces, we cannot
741 * send two ROI's (for each half). We merge them into single ROI and split
742 * them across lSplit for MDP mixer use. The ROI's will be merged again
743 * finally before udpating the panel in the driver. */
744 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
745 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
746 l_roi = getIntersection(temp_roi, l_frame);
747 r_roi = getIntersection(temp_roi, r_frame);
748 }
749
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800750 /* No layer is updating. Still SF wants a refresh. */
751 if(!isValidRect(l_roi) && !isValidRect(r_roi))
752 return;
753
754 l_roi = getSanitizeROI(l_roi, l_frame);
755 r_roi = getSanitizeROI(r_roi, r_frame);
756
757 ctx->listStats[mDpy].lRoi = l_roi;
758 ctx->listStats[mDpy].rRoi = r_roi;
759
760 if(!validateAndApplyROI(ctx, list))
761 resetROI(ctx, mDpy);
762
763 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
764 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
765 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
766 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
767 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
768 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700769}
770
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800771/* Checks for conditions where all the layers marked for MDP comp cannot be
772 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800773bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800774 hwc_display_contents_1_t* list){
775
Saurabh Shahaa236822013-04-24 18:07:26 -0700776 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800777
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700778 // Fall back to video only composition, if AIV video mode is enabled
779 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700780 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
781 __FUNCTION__, mDpy);
782 return false;
783 }
784
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530785 /* No Idle fall back if secure display or secure RGB layers are present
786 * or if there is only a single layer being composed */
787 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
788 !ctx->listStats[mDpy].secureRGBCount &&
789 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700790 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
791 return false;
792 }
793
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700794 // if secondary is configuring or Padding round, fall back to video only
795 // composition and release all assigned non VIG pipes from primary.
796 if(isSecondaryConfiguring(ctx)) {
797 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
798 __FUNCTION__);
799 return false;
800 } else if(ctx->isPaddingRound) {
801 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
802 __FUNCTION__,mDpy);
803 return false;
804 }
805
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700806 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800807 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700808 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800809 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
810 return false;
811 }
812
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800813 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800814 hwc_layer_1_t* layer = &list->hwLayers[i];
815 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800816
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800817 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700818 if(!canUseRotator(ctx, mDpy)) {
819 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
820 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700821 return false;
822 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800823 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530824
825 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
826 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800827 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700828 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530829 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
830 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
831 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800832 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700833
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700834 if(ctx->mAD->isDoable()) {
835 return false;
836 }
837
Saurabh Shahaa236822013-04-24 18:07:26 -0700838 //If all above hard conditions are met we can do full or partial MDP comp.
839 bool ret = false;
840 if(fullMDPComp(ctx, list)) {
841 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700842 } else if(fullMDPCompWithPTOR(ctx, list)) {
843 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700844 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700845 ret = true;
846 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530847
Saurabh Shahaa236822013-04-24 18:07:26 -0700848 return ret;
849}
850
851bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700852
853 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
854 return false;
855
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700856 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
857 for(int i = 0; i < numAppLayers; i++) {
858 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700859 if(not mCurrentFrame.drop[i] and
860 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700861 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
862 return false;
863 }
864 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800865
Saurabh Shahaa236822013-04-24 18:07:26 -0700866 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700867 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
868 sizeof(mCurrentFrame.isFBComposed));
869 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
870 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700871
Raj Kamal389d6e32014-08-04 14:43:24 +0530872 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800873 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530874 }
875
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800876 if(!postHeuristicsHandling(ctx, list)) {
877 ALOGD_IF(isDebug(), "post heuristic handling failed");
878 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700879 return false;
880 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700881 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
882 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700883 return true;
884}
885
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886/* Full MDP Composition with Peripheral Tiny Overlap Removal.
887 * MDP bandwidth limitations can be avoided, if the overlap region
888 * covered by the smallest layer at a higher z-order, gets composed
889 * by Copybit on a render buffer, which can be queued to MDP.
890 */
891bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
892 hwc_display_contents_1_t* list) {
893
894 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
895 const int stagesForMDP = min(sMaxPipesPerMixer,
896 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
897
898 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700899 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700900 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
901 return false;
902 }
903
904 // Frame level checks
905 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
906 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
907 isSecurePresent(ctx, mDpy)) {
908 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
909 return false;
910 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700911 // MDP comp checks
912 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700913 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700914 if(not isSupportedForMDPComp(ctx, layer)) {
915 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
916 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700917 }
918 }
919
Sushil Chauhandefd3522014-05-13 18:17:12 -0700920 /* We cannot use this composition mode, if:
921 1. A below layer needs scaling.
922 2. Overlap is not peripheral to display.
923 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700924 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700925 */
926
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700927 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
928 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
929 memset(overlapRect, 0, sizeof(overlapRect));
930 int layerPixelCount, minPixelCount = 0;
931 int numPTORLayersFound = 0;
932 for (int i = numAppLayers-1; (i >= 0 &&
933 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700934 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700935 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700936 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700937 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
938 // PTOR layer should be peripheral and cannot have transform
939 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
940 has90Transform(layer)) {
941 continue;
942 }
943 if((3 * (layerPixelCount + minPixelCount)) >
944 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
945 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
946 continue;
947 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700948 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700949 for (int j = i-1; j >= 0; j--) {
950 // Check if the layers below this layer qualifies for PTOR comp
951 hwc_layer_1_t* layer = &list->hwLayers[j];
952 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700953 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700954 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700955 if (isValidRect(getIntersection(dispFrame, disFrame))) {
956 if (has90Transform(layer) || needsScaling(layer)) {
957 found = false;
958 break;
959 }
960 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700961 }
962 }
963 // Store the minLayer Index
964 if(found) {
965 minLayerIndex[numPTORLayersFound] = i;
966 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
967 minPixelCount += layerPixelCount;
968 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700969 }
970 }
971
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700972 // No overlap layers
973 if (!numPTORLayersFound)
974 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700975
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700976 // Store the displayFrame and the sourceCrops of the layers
977 hwc_rect_t displayFrame[numAppLayers];
978 hwc_rect_t sourceCrop[numAppLayers];
979 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700980 hwc_layer_1_t* layer = &list->hwLayers[i];
981 displayFrame[i] = layer->displayFrame;
982 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700984
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530985 /**
986 * It's possible that 2 PTOR layers might have overlapping.
987 * In such case, remove the intersection(again if peripheral)
988 * from the lower PTOR layer to avoid overlapping.
989 * If intersection is not on peripheral then compromise
990 * by reducing number of PTOR layers.
991 **/
992 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
993 if(isValidRect(commonRect)) {
994 overlapRect[1] = deductRect(overlapRect[1], commonRect);
995 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
996 }
997
998 ctx->mPtorInfo.count = numPTORLayersFound;
999 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1000 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1001 }
1002
1003 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1004 // reset PTOR
1005 ctx->mPtorInfo.count = 0;
1006 if(isValidRect(commonRect)) {
1007 // If PTORs are intersecting restore displayframe of PTOR[1]
1008 // before returning, as we have modified it above.
1009 list->hwLayers[minLayerIndex[1]].displayFrame =
1010 displayFrame[minLayerIndex[1]];
1011 }
1012 return false;
1013 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001014 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1015 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1016
Xu Yangcda012c2014-07-30 21:57:21 +08001017 // Store the blending mode, planeAlpha, and transform of PTOR layers
1018 int32_t blending[numPTORLayersFound];
1019 uint8_t planeAlpha[numPTORLayersFound];
1020 uint32_t transform[numPTORLayersFound];
1021
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001022 for(int j = 0; j < numPTORLayersFound; j++) {
1023 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001024
1025 // Update src crop of PTOR layer
1026 hwc_layer_1_t* layer = &list->hwLayers[index];
1027 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1028 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1029 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1030 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1031
1032 // Store & update w, h, format of PTOR layer
1033 private_handle_t *hnd = (private_handle_t *)layer->handle;
1034 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1035 layerWhf[j] = whf;
1036 hnd->width = renderBuf->width;
1037 hnd->height = renderBuf->height;
1038 hnd->format = renderBuf->format;
1039
Xu Yangcda012c2014-07-30 21:57:21 +08001040 // Store & update blending mode, planeAlpha and transform of PTOR layer
1041 blending[j] = layer->blending;
1042 planeAlpha[j] = layer->planeAlpha;
1043 transform[j] = layer->transform;
1044 layer->blending = HWC_BLENDING_NONE;
1045 layer->planeAlpha = 0xFF;
1046 layer->transform = 0;
1047
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001048 // Remove overlap from crop & displayFrame of below layers
1049 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001050 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001051 if(!isValidRect(getIntersection(layer->displayFrame,
1052 overlapRect[j]))) {
1053 continue;
1054 }
1055 // Update layer attributes
1056 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1057 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301058 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001059 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1060 layer->transform);
1061 layer->sourceCropf.left = (float)srcCrop.left;
1062 layer->sourceCropf.top = (float)srcCrop.top;
1063 layer->sourceCropf.right = (float)srcCrop.right;
1064 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1065 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001066 }
1067
1068 mCurrentFrame.mdpCount = numAppLayers;
1069 mCurrentFrame.fbCount = 0;
1070 mCurrentFrame.fbZ = -1;
1071
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301072 for (int j = 0; j < numAppLayers; j++) {
1073 if(isValidRect(list->hwLayers[j].displayFrame)) {
1074 mCurrentFrame.isFBComposed[j] = false;
1075 } else {
1076 mCurrentFrame.mdpCount--;
1077 mCurrentFrame.drop[j] = true;
1078 }
1079 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001080
1081 bool result = postHeuristicsHandling(ctx, list);
1082
1083 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001084 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001085 hwc_layer_1_t* layer = &list->hwLayers[i];
1086 layer->displayFrame = displayFrame[i];
1087 layer->sourceCropf.left = (float)sourceCrop[i].left;
1088 layer->sourceCropf.top = (float)sourceCrop[i].top;
1089 layer->sourceCropf.right = (float)sourceCrop[i].right;
1090 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1091 }
1092
Xu Yangcda012c2014-07-30 21:57:21 +08001093 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001094 for (int i = 0; i < numPTORLayersFound; i++) {
1095 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001096 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001097 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1098 hnd->width = layerWhf[i].w;
1099 hnd->height = layerWhf[i].h;
1100 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001101 layer->blending = blending[i];
1102 layer->planeAlpha = planeAlpha[i];
1103 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001104 }
1105
Sushil Chauhandefd3522014-05-13 18:17:12 -07001106 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001107 // reset PTOR
1108 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001109 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001110 } else {
1111 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1112 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001113 }
1114
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001115 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1116 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001117 return result;
1118}
1119
Saurabh Shahaa236822013-04-24 18:07:26 -07001120bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1121{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001122 if(!sEnableMixedMode) {
1123 //Mixed mode is disabled. No need to even try caching.
1124 return false;
1125 }
1126
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001127 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301128 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1129 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001130 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001131 cacheBasedComp(ctx, list);
1132 } else {
1133 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001134 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001135 }
1136
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001137 return ret;
1138}
1139
1140bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1141 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001142 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1143 return false;
1144
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001145 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001146 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001147 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001148
1149 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1150 for(int i = 0; i < numAppLayers; i++) {
1151 if(!mCurrentFrame.isFBComposed[i]) {
1152 hwc_layer_1_t* layer = &list->hwLayers[i];
1153 if(not isSupportedForMDPComp(ctx, layer)) {
1154 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1155 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001156 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001157 return false;
1158 }
1159 }
1160 }
1161
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001162 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001163 /* mark secure RGB layers for MDP comp */
1164 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301165 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001166 if(!ret) {
1167 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001168 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001169 return false;
1170 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001171
1172 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001173
Raj Kamal389d6e32014-08-04 14:43:24 +05301174 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001175 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301176 }
1177
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001178 if(!postHeuristicsHandling(ctx, list)) {
1179 ALOGD_IF(isDebug(), "post heuristic handling failed");
1180 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001181 return false;
1182 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001183 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1184 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001185
Saurabh Shahaa236822013-04-24 18:07:26 -07001186 return true;
1187}
1188
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001189bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001190 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001191 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1192 return false;
1193
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001194 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001195 return false;
1196 }
1197
Saurabh Shahb772ae32013-11-18 15:40:02 -08001198 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001199 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1200 const int stagesForMDP = min(sMaxPipesPerMixer,
1201 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001202
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001203 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1204 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1205 int lastMDPSupportedIndex = numAppLayers;
1206 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001207
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001208 //Find the minimum MDP batch size
1209 for(int i = 0; i < numAppLayers;i++) {
1210 if(mCurrentFrame.drop[i]) {
1211 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001212 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001213 }
1214 hwc_layer_1_t* layer = &list->hwLayers[i];
1215 if(not isSupportedForMDPComp(ctx, layer)) {
1216 lastMDPSupportedIndex = i;
1217 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1218 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001219 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001220 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001221 }
1222
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001223 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1224 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1225 mCurrentFrame.dropCount);
1226
1227 //Start at a point where the fb batch should at least have 2 layers, for
1228 //this mode to be justified.
1229 while(fbBatchSize < 2) {
1230 ++fbBatchSize;
1231 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001232 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001233
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001234 //If there are no layers for MDP, this mode doesnt make sense.
1235 if(mdpBatchSize < 1) {
1236 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1237 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001238 return false;
1239 }
1240
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001241 mCurrentFrame.reset(numAppLayers);
1242
1243 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1244 while(mdpBatchSize > 0) {
1245 //Mark layers for MDP comp
1246 int mdpBatchLeft = mdpBatchSize;
1247 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1248 if(mCurrentFrame.drop[i]) {
1249 continue;
1250 }
1251 mCurrentFrame.isFBComposed[i] = false;
1252 --mdpBatchLeft;
1253 }
1254
1255 mCurrentFrame.fbZ = mdpBatchSize;
1256 mCurrentFrame.fbCount = fbBatchSize;
1257 mCurrentFrame.mdpCount = mdpBatchSize;
1258
1259 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1260 __FUNCTION__, mdpBatchSize, fbBatchSize,
1261 mCurrentFrame.dropCount);
1262
1263 if(postHeuristicsHandling(ctx, list)) {
1264 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001265 __FUNCTION__);
1266 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1267 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001268 return true;
1269 }
1270
1271 reset(ctx);
1272 --mdpBatchSize;
1273 ++fbBatchSize;
1274 }
1275
1276 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001277}
1278
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001279bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301280 if(mDpy or isSecurePresent(ctx, mDpy) or
1281 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001282 return false;
1283 }
1284 return true;
1285}
1286
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001287bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1288 hwc_display_contents_1_t* list){
1289 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1290 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001291 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001292 return false;
1293 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001294 if(ctx->listStats[mDpy].secureUI)
1295 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001296 return true;
1297}
1298
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001299bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1300 hwc_display_contents_1_t* list) {
1301 const bool secureOnly = true;
1302 return videoOnlyComp(ctx, list, not secureOnly) or
1303 videoOnlyComp(ctx, list, secureOnly);
1304}
1305
1306bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001307 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001308 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1309 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301310
Saurabh Shahaa236822013-04-24 18:07:26 -07001311 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301312 if(!isSecurePresent(ctx, mDpy)) {
1313 /* Bail out if we are processing only secured video layers
1314 * and we dont have any */
1315 if(secureOnly) {
1316 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1317 return false;
1318 }
1319 /* No Idle fall back for secure video layers and if there is only
1320 * single layer being composed. */
1321 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1322 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1323 return false;
1324 }
1325 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001326
Saurabh Shahaa236822013-04-24 18:07:26 -07001327 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001328 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001329 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001330 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001331
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001332 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1333 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001334 return false;
1335 }
1336
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001337 if(mCurrentFrame.fbCount)
1338 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001339
Raj Kamal389d6e32014-08-04 14:43:24 +05301340 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001341 adjustForSourceSplit(ctx, list);
1342 }
1343
1344 if(!postHeuristicsHandling(ctx, list)) {
1345 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301346 if(errno == ENOBUFS) {
1347 ALOGD_IF(isDebug(), "SMP Allocation failed");
1348 //On SMP allocation failure in video only comp add padding round
1349 ctx->isPaddingRound = true;
1350 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001351 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001352 return false;
1353 }
1354
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001355 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1356 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001357 return true;
1358}
1359
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001360/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1361bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1362 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001363 // Fall back to video only composition, if AIV video mode is enabled
1364 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001365 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1366 __FUNCTION__, mDpy);
1367 return false;
1368 }
1369
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001370 const bool secureOnly = true;
1371 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1372 mdpOnlyLayersComp(ctx, list, secureOnly);
1373
1374}
1375
1376bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1377 hwc_display_contents_1_t* list, bool secureOnly) {
1378
1379 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1380 return false;
1381
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301382 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1383 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1384 /* Bail out if we are processing only secured video/ui layers
1385 * and we dont have any */
1386 if(secureOnly) {
1387 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1388 return false;
1389 }
1390 /* No Idle fall back for secure video/ui layers and if there is only
1391 * single layer being composed. */
1392 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1393 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1394 return false;
1395 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001396 }
1397
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001398 /* Bail out if we dont have any secure RGB layers */
1399 if (!ctx->listStats[mDpy].secureRGBCount) {
1400 reset(ctx);
1401 return false;
1402 }
1403
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001404 mCurrentFrame.reset(numAppLayers);
1405 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1406
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001407 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001408 /* mark secure RGB layers for MDP comp */
1409 updateSecureRGB(ctx, list);
1410
1411 if(mCurrentFrame.mdpCount == 0) {
1412 reset(ctx);
1413 return false;
1414 }
1415
1416 /* find the maximum batch of layers to be marked for framebuffer */
1417 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1418 if(!ret) {
1419 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1420 reset(ctx);
1421 return false;
1422 }
1423
1424 if(sEnableYUVsplit){
1425 adjustForSourceSplit(ctx, list);
1426 }
1427
1428 if(!postHeuristicsHandling(ctx, list)) {
1429 ALOGD_IF(isDebug(), "post heuristic handling failed");
1430 reset(ctx);
1431 return false;
1432 }
1433
1434 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1435 __FUNCTION__);
1436 return true;
1437}
1438
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001439/* Checks for conditions where YUV layers cannot be bypassed */
1440bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001441 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001442 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001443 return false;
1444 }
1445
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001446 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001447 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1448 return false;
1449 }
1450
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001451 if(isSecuring(ctx, layer)) {
1452 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1453 return false;
1454 }
1455
Saurabh Shah4fdde762013-04-30 18:47:33 -07001456 if(!isValidDimension(ctx, layer)) {
1457 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1458 __FUNCTION__);
1459 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001460 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001461
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001462 if(layer->planeAlpha < 0xFF) {
1463 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1464 in video only mode",
1465 __FUNCTION__);
1466 return false;
1467 }
1468
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001469 return true;
1470}
1471
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001472/* Checks for conditions where Secure RGB layers cannot be bypassed */
1473bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1474 if(isSkipLayer(layer)) {
1475 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1476 __FUNCTION__, mDpy);
1477 return false;
1478 }
1479
1480 if(isSecuring(ctx, layer)) {
1481 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1482 return false;
1483 }
1484
1485 if(not isSupportedForMDPComp(ctx, layer)) {
1486 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1487 __FUNCTION__);
1488 return false;
1489 }
1490 return true;
1491}
1492
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301493/* starts at fromIndex and check for each layer to find
1494 * if it it has overlapping with any Updating layer above it in zorder
1495 * till the end of the batch. returns true if it finds any intersection */
1496bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1497 int fromIndex, int toIndex) {
1498 for(int i = fromIndex; i < toIndex; i++) {
1499 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1500 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1501 return false;
1502 }
1503 }
1504 }
1505 return true;
1506}
1507
1508/* Checks if given layer at targetLayerIndex has any
1509 * intersection with all the updating layers in beween
1510 * fromIndex and toIndex. Returns true if it finds intersectiion */
1511bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1512 int fromIndex, int toIndex, int targetLayerIndex) {
1513 for(int i = fromIndex; i <= toIndex; i++) {
1514 if(!mCurrentFrame.isFBComposed[i]) {
1515 if(areLayersIntersecting(&list->hwLayers[i],
1516 &list->hwLayers[targetLayerIndex])) {
1517 return true;
1518 }
1519 }
1520 }
1521 return false;
1522}
1523
1524int MDPComp::getBatch(hwc_display_contents_1_t* list,
1525 int& maxBatchStart, int& maxBatchEnd,
1526 int& maxBatchCount) {
1527 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301528 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001529 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301530 while (i < mCurrentFrame.layerCount) {
1531 int batchCount = 0;
1532 int batchStart = i;
1533 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001534 /* Adjust batch Z order with the dropped layers so far */
1535 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301536 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301537 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301538 while(i < mCurrentFrame.layerCount) {
1539 if(!mCurrentFrame.isFBComposed[i]) {
1540 if(!batchCount) {
1541 i++;
1542 break;
1543 }
1544 updatingLayersAbove++;
1545 i++;
1546 continue;
1547 } else {
1548 if(mCurrentFrame.drop[i]) {
1549 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001550 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301551 continue;
1552 } else if(updatingLayersAbove <= 0) {
1553 batchCount++;
1554 batchEnd = i;
1555 i++;
1556 continue;
1557 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1558
1559 // We have a valid updating layer already. If layer-i not
1560 // have overlapping with all updating layers in between
1561 // batch-start and i, then we can add layer i to batch.
1562 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1563 batchCount++;
1564 batchEnd = i;
1565 i++;
1566 continue;
1567 } else if(canPushBatchToTop(list, batchStart, i)) {
1568 //If All the non-updating layers with in this batch
1569 //does not have intersection with the updating layers
1570 //above in z-order, then we can safely move the batch to
1571 //higher z-order. Increment fbZ as it is moving up.
1572 if( firstZReverseIndex < 0) {
1573 firstZReverseIndex = i;
1574 }
1575 batchCount++;
1576 batchEnd = i;
1577 fbZ += updatingLayersAbove;
1578 i++;
1579 updatingLayersAbove = 0;
1580 continue;
1581 } else {
1582 //both failed.start the loop again from here.
1583 if(firstZReverseIndex >= 0) {
1584 i = firstZReverseIndex;
1585 }
1586 break;
1587 }
1588 }
1589 }
1590 }
1591 if(batchCount > maxBatchCount) {
1592 maxBatchCount = batchCount;
1593 maxBatchStart = batchStart;
1594 maxBatchEnd = batchEnd;
1595 fbZOrder = fbZ;
1596 }
1597 }
1598 return fbZOrder;
1599}
1600
1601bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1602 hwc_display_contents_1_t* list) {
1603 /* Idea is to keep as many non-updating(cached) layers in FB and
1604 * send rest of them through MDP. This is done in 2 steps.
1605 * 1. Find the maximum contiguous batch of non-updating layers.
1606 * 2. See if we can improve this batch size for caching by adding
1607 * opaque layers around the batch, if they don't have
1608 * any overlapping with the updating layers in between.
1609 * NEVER mark an updating layer for caching.
1610 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001611
1612 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001613 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001614 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301615 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001617 /* Nothing is cached. No batching needed */
1618 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001619 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001620 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001621
1622 /* No MDP comp layers, try to use other comp modes */
1623 if(mCurrentFrame.mdpCount == 0) {
1624 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001625 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301627 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001628
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301629 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001630 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001631 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001632 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301633 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001634 if(!mCurrentFrame.drop[i]){
1635 //If an unsupported layer is being attempted to
1636 //be pulled out we should fail
1637 if(not isSupportedForMDPComp(ctx, layer)) {
1638 return false;
1639 }
1640 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001641 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001642 }
1643 }
1644
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301645 // update the frame data
1646 mCurrentFrame.fbZ = fbZ;
1647 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001648 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001649 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001650
1651 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301652 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001653
1654 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001655}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001656
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001657void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001658 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001659 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001660 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001661
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 for(int i = 0; i < numAppLayers; i++) {
1663 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001664 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001665 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001666 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001667 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001668 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001669 }
1670 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001671
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001672 frame.fbCount = fbCount;
1673 frame.mdpCount = frame.layerCount - frame.fbCount
1674 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001675
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001676 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1677 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678}
1679
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001680// drop other non-AIV layers from external display list.
1681void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001682 hwc_display_contents_1_t* list) {
1683 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1684 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001685 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001686 mCurrentFrame.dropCount++;
1687 mCurrentFrame.drop[i] = true;
1688 }
1689 }
1690 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1691 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1692 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1693 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1694 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1695 mCurrentFrame.dropCount);
1696}
1697
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001698void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001699 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001700 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1701 for(int index = 0;index < nYuvCount; index++){
1702 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1703 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1704
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001705 if(mCurrentFrame.drop[nYuvIndex]) {
1706 continue;
1707 }
1708
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001709 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001710 if(!frame.isFBComposed[nYuvIndex]) {
1711 frame.isFBComposed[nYuvIndex] = true;
1712 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001713 }
1714 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001715 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001716 private_handle_t *hnd = (private_handle_t *)layer->handle;
1717 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001718 frame.isFBComposed[nYuvIndex] = false;
1719 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001720 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001721 }
1722 }
1723 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001724
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001725 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1726 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727}
1728
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001729void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1730 hwc_display_contents_1_t* list) {
1731 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1732 for(int index = 0;index < nSecureRGBCount; index++){
1733 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1734 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1735
1736 if(!isSecureRGBDoable(ctx, layer)) {
1737 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1738 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1739 mCurrentFrame.fbCount++;
1740 }
1741 } else {
1742 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1743 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1744 mCurrentFrame.fbCount--;
1745 }
1746 }
1747 }
1748
1749 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1750 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1751 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1752 mCurrentFrame.fbCount);
1753}
1754
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001755hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1756 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001757 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001758
1759 /* Update only the region of FB needed for composition */
1760 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1761 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1762 hwc_layer_1_t* layer = &list->hwLayers[i];
1763 hwc_rect_t dst = layer->displayFrame;
1764 fbRect = getUnion(fbRect, dst);
1765 }
1766 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001767 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001768 return fbRect;
1769}
1770
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001771bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1772 hwc_display_contents_1_t* list) {
1773
1774 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001775 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001776 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1777 return false;
1778 }
1779
1780 //Limitations checks
1781 if(!hwLimitationsCheck(ctx, list)) {
1782 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1783 return false;
1784 }
1785
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001786 //Configure framebuffer first if applicable
1787 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001788 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001789 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1790 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001791 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1792 __FUNCTION__);
1793 return false;
1794 }
1795 }
1796
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001797 mCurrentFrame.map();
1798
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001799 if(!allocLayerPipes(ctx, list)) {
1800 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001801 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001802 }
1803
1804 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001805 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001806 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001807 int mdpIndex = mCurrentFrame.layerToMDP[index];
1808 hwc_layer_1_t* layer = &list->hwLayers[index];
1809
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301810 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1811 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1812 mdpNextZOrder++;
1813 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1815 cur_pipe->zOrder = mdpNextZOrder++;
1816
radhakrishnac9a67412013-09-25 17:40:42 +05301817 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301818 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301819 if(configure4k2kYuv(ctx, layer,
1820 mCurrentFrame.mdpToLayer[mdpIndex])
1821 != 0 ){
1822 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1823 for layer %d",__FUNCTION__, index);
1824 return false;
1825 }
1826 else{
1827 mdpNextZOrder++;
1828 }
1829 continue;
1830 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001831 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1832 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301833 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001834 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001835 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001836 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001837 }
1838
Saurabh Shaha36be922013-12-16 18:18:39 -08001839 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1840 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1841 ,__FUNCTION__, mDpy);
1842 return false;
1843 }
1844
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001845 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001846 return true;
1847}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001848
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001849bool MDPComp::resourceCheck(hwc_context_t* ctx,
1850 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001851 const bool fbUsed = mCurrentFrame.fbCount;
1852 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1853 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1854 return false;
1855 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001856
1857 //Will benefit cases where a video has non-updating background.
1858 if((mDpy > HWC_DISPLAY_PRIMARY) and
1859 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1860 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1861 return false;
1862 }
1863
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001864 // Init rotCount to number of rotate sessions used by other displays
1865 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1866 // Count the number of rotator sessions required for current display
1867 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1868 if(!mCurrentFrame.isFBComposed[index]) {
1869 hwc_layer_1_t* layer = &list->hwLayers[index];
1870 private_handle_t *hnd = (private_handle_t *)layer->handle;
1871 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1872 rotCount++;
1873 }
1874 }
1875 }
1876 // if number of layers to rotate exceeds max rotator sessions, bail out.
1877 if(rotCount > RotMgr::MAX_ROT_SESS) {
1878 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1879 __FUNCTION__, mDpy);
1880 return false;
1881 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001882 return true;
1883}
1884
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301885bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1886 hwc_display_contents_1_t* list) {
1887
1888 //A-family hw limitation:
1889 //If a layer need alpha scaling, MDP can not support.
1890 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1891 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1892 if(!mCurrentFrame.isFBComposed[i] &&
1893 isAlphaScaled( &list->hwLayers[i])) {
1894 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1895 return false;
1896 }
1897 }
1898 }
1899
1900 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1901 //If multiple layers requires downscaling and also they are overlapping
1902 //fall back to GPU since MDSS can not handle it.
1903 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1904 qdutils::MDPVersion::getInstance().is8x26()) {
1905 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1906 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1907 if(!mCurrentFrame.isFBComposed[i] &&
1908 isDownscaleRequired(botLayer)) {
1909 //if layer-i is marked for MDP and needs downscaling
1910 //check if any MDP layer on top of i & overlaps with layer-i
1911 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1912 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1913 if(!mCurrentFrame.isFBComposed[j] &&
1914 isDownscaleRequired(topLayer)) {
1915 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1916 topLayer->displayFrame);
1917 if(isValidRect(r))
1918 return false;
1919 }
1920 }
1921 }
1922 }
1923 }
1924 return true;
1925}
1926
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001927// Checks only if videos or single layer(RGB) is updating
1928// which is used for setting dynamic fps or perf hint for single
1929// layer video playback
1930bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1931 hwc_display_contents_1_t* list) {
1932 bool support = false;
1933 FrameInfo frame;
1934 frame.reset(mCurrentFrame.layerCount);
1935 memset(&frame.drop, 0, sizeof(frame.drop));
1936 frame.dropCount = 0;
1937 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1938 updateLayerCache(ctx, list, frame);
1939 updateYUV(ctx, list, false /*secure only*/, frame);
1940 // There are only updating YUV layers or there is single RGB
1941 // Layer(Youtube)
1942 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1943 (frame.layerCount == 1)) {
1944 support = true;
1945 }
1946 return support;
1947}
1948
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301949void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1950 //For primary display, set the dynamic refreshrate
1951 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1952 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301953 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1954 MDPVersion& mdpHw = MDPVersion::getInstance();
1955 if(sIdleFallBack) {
1956 //Set minimum panel refresh rate during idle timeout
1957 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001958 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301959 //Set the new fresh rate, if there is only one updating YUV layer
1960 //or there is one single RGB layer with this request
1961 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1962 }
1963 setRefreshRate(ctx, mDpy, refreshRate);
1964 }
1965}
1966
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001967int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001968 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001969 char property[PROPERTY_VALUE_MAX];
1970
Raj Kamal4393eaa2014-06-06 13:45:20 +05301971 if(!ctx || !list) {
1972 ALOGE("%s: Invalid context or list",__FUNCTION__);
1973 mCachedFrame.reset();
1974 return -1;
1975 }
1976
1977 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001978 if(mDpy == HWC_DISPLAY_PRIMARY) {
1979 sSimulationFlags = 0;
1980 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1981 int currentFlags = atoi(property);
1982 if(currentFlags != sSimulationFlags) {
1983 sSimulationFlags = currentFlags;
1984 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1985 sSimulationFlags, sSimulationFlags);
1986 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001987 }
1988 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001989 // reset PTOR
1990 if(!mDpy)
1991 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001992
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301993 //reset old data
1994 mCurrentFrame.reset(numLayers);
1995 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1996 mCurrentFrame.dropCount = 0;
1997
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301998 //Do not cache the information for next draw cycle.
1999 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2000 ALOGI("%s: Unsupported layer count for mdp composition",
2001 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002002 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302003#ifdef DYNAMIC_FPS
2004 setDynRefreshRate(ctx, list);
2005#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002006 return -1;
2007 }
2008
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002009 // Detect the start of animation and fall back to GPU only once to cache
2010 // all the layers in FB and display FB content untill animation completes.
2011 if(ctx->listStats[mDpy].isDisplayAnimating) {
2012 mCurrentFrame.needsRedraw = false;
2013 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2014 mCurrentFrame.needsRedraw = true;
2015 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2016 }
2017 setMDPCompLayerFlags(ctx, list);
2018 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302019#ifdef DYNAMIC_FPS
2020 setDynRefreshRate(ctx, list);
2021#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002022 ret = -1;
2023 return ret;
2024 } else {
2025 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2026 }
2027
Saurabh Shahb39f8152013-08-22 10:21:44 -07002028 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002029 if(isFrameDoable(ctx)) {
2030 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002031 // if AIV Video mode is enabled, drop all non AIV layers from the
2032 // external display list.
2033 if(ctx->listStats[mDpy].mAIVVideoMode) {
2034 dropNonAIVLayers(ctx, list);
2035 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002036
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002037 // if tryFullFrame fails, try to push all video and secure RGB layers
2038 // to MDP for composition.
2039 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002040 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302041 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002042 setMDPCompLayerFlags(ctx, list);
2043 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002044 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002045 reset(ctx);
2046 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2047 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002048 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002049 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2050 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002051 }
2052 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302053 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2054 enablePartialUpdateForMDP3) {
2055 generateROI(ctx, list);
2056 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2057 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2058 }
2059 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002060 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2061 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002062 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002063 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002064
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002065 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002066 ALOGD("GEOMETRY change: %d",
2067 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002068 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002069 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002070 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002071 }
2072
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002073#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302074 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002075#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002076 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002077
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002078 mCachedFrame.cacheAll(list);
2079 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002080 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002081}
2082
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002083bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302084
2085 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302086 int mdpIndex = mCurrentFrame.layerToMDP[index];
2087 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2088 info.pipeInfo = new MdpYUVPipeInfo;
2089 info.rot = NULL;
2090 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302091
2092 pipe_info.lIndex = ovutils::OV_INVALID;
2093 pipe_info.rIndex = ovutils::OV_INVALID;
2094
Saurabh Shahc62f3982014-03-05 14:28:26 -08002095 Overlay::PipeSpecs pipeSpecs;
2096 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2097 pipeSpecs.needsScaling = true;
2098 pipeSpecs.dpy = mDpy;
2099 pipeSpecs.fb = false;
2100
2101 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302102 if(pipe_info.lIndex == ovutils::OV_INVALID){
2103 bRet = false;
2104 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2105 __FUNCTION__);
2106 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002107 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302108 if(pipe_info.rIndex == ovutils::OV_INVALID){
2109 bRet = false;
2110 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2111 __FUNCTION__);
2112 }
2113 return bRet;
2114}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002115
2116int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2117 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002118 if (ctx->mPtorInfo.isActive()) {
2119 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002120 if (fd < 0) {
2121 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002122 }
2123 }
2124 return fd;
2125}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002126//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002127
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002128void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302129 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002130 //If 4k2k Yuv layer split is possible, and if
2131 //fbz is above 4k2k layer, increment fb zorder by 1
2132 //as we split 4k2k layer and increment zorder for right half
2133 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002134 if(!ctx)
2135 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002136 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302137 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2138 index++) {
2139 if(!mCurrentFrame.isFBComposed[index]) {
2140 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2141 mdpNextZOrder++;
2142 }
2143 mdpNextZOrder++;
2144 hwc_layer_1_t* layer = &list->hwLayers[index];
2145 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302146 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302147 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2148 mCurrentFrame.fbZ += 1;
2149 mdpNextZOrder++;
2150 //As we split 4kx2k yuv layer and program to 2 VG pipes
2151 //(if available) increase mdpcount by 1.
2152 mCurrentFrame.mdpCount++;
2153 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002154 }
2155 }
2156 }
radhakrishnac9a67412013-09-25 17:40:42 +05302157}
2158
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002159/*
2160 * Configures pipe(s) for MDP composition
2161 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002162int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002163 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002164 MdpPipeInfoNonSplit& mdp_info =
2165 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302166 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002167 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002168 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002169
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002170 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2171 __FUNCTION__, layer, zOrder, dest);
2172
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002173 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002174 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002175}
2176
Saurabh Shah88e4d272013-09-03 13:31:29 -07002177bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002178 hwc_display_contents_1_t* list) {
2179 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002180
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002181 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002182
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002183 hwc_layer_1_t* layer = &list->hwLayers[index];
2184 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302185 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002186 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302187 continue;
2188 }
2189 }
2190
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002191 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002192 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002193 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002194 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002195 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002196
Saurabh Shahc62f3982014-03-05 14:28:26 -08002197 Overlay::PipeSpecs pipeSpecs;
2198 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2199 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2200 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2201 (qdutils::MDPVersion::getInstance().is8x26() and
2202 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2203 pipeSpecs.dpy = mDpy;
2204 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002205 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002206
Saurabh Shahc62f3982014-03-05 14:28:26 -08002207 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2208
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002209 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002210 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002211 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002212 }
2213 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002214 return true;
2215}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002216
radhakrishnac9a67412013-09-25 17:40:42 +05302217int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2218 PipeLayerPair& PipeLayerPair) {
2219 MdpYUVPipeInfo& mdp_info =
2220 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2221 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302222 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302223 eDest lDest = mdp_info.lIndex;
2224 eDest rDest = mdp_info.rIndex;
2225
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002226 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302227 lDest, rDest, &PipeLayerPair.rot);
2228}
2229
Saurabh Shah88e4d272013-09-03 13:31:29 -07002230bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002231
Raj Kamal4393eaa2014-06-06 13:45:20 +05302232 if(!isEnabled() or !mModeOn) {
2233 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302234 return true;
2235 }
2236
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002237 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002238 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002239 sHandleTimeout = true;
2240 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002241
2242 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002243 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002244
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002245 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2246 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002247 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002248 if(mCurrentFrame.isFBComposed[i]) continue;
2249
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002250 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002251 private_handle_t *hnd = (private_handle_t *)layer->handle;
2252 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002253 if (!(layer->flags & HWC_COLOR_FILL)) {
2254 ALOGE("%s handle null", __FUNCTION__);
2255 return false;
2256 }
2257 // No PLAY for Color layer
2258 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2259 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002260 }
2261
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002262 int mdpIndex = mCurrentFrame.layerToMDP[i];
2263
Raj Kamal389d6e32014-08-04 14:43:24 +05302264 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302265 {
2266 MdpYUVPipeInfo& pipe_info =
2267 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2268 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2269 ovutils::eDest indexL = pipe_info.lIndex;
2270 ovutils::eDest indexR = pipe_info.rIndex;
2271 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302272 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302273 if(rot) {
2274 rot->queueBuffer(fd, offset);
2275 fd = rot->getDstMemId();
2276 offset = rot->getDstOffset();
2277 }
2278 if(indexL != ovutils::OV_INVALID) {
2279 ovutils::eDest destL = (ovutils::eDest)indexL;
2280 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2281 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2282 if (!ov.queueBuffer(fd, offset, destL)) {
2283 ALOGE("%s: queueBuffer failed for display:%d",
2284 __FUNCTION__, mDpy);
2285 return false;
2286 }
2287 }
2288
2289 if(indexR != ovutils::OV_INVALID) {
2290 ovutils::eDest destR = (ovutils::eDest)indexR;
2291 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2292 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2293 if (!ov.queueBuffer(fd, offset, destR)) {
2294 ALOGE("%s: queueBuffer failed for display:%d",
2295 __FUNCTION__, mDpy);
2296 return false;
2297 }
2298 }
2299 }
2300 else{
2301 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002302 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302303 ovutils::eDest dest = pipe_info.index;
2304 if(dest == ovutils::OV_INVALID) {
2305 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002306 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302307 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002308
radhakrishnac9a67412013-09-25 17:40:42 +05302309 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2310 continue;
2311 }
2312
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002313 int fd = hnd->fd;
2314 uint32_t offset = (uint32_t)hnd->offset;
2315 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2316 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002317 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002318 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002319 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002320 }
2321
radhakrishnac9a67412013-09-25 17:40:42 +05302322 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2323 using pipe: %d", __FUNCTION__, layer,
2324 hnd, dest );
2325
radhakrishnac9a67412013-09-25 17:40:42 +05302326 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2327 if(rot) {
2328 if(!rot->queueBuffer(fd, offset))
2329 return false;
2330 fd = rot->getDstMemId();
2331 offset = rot->getDstOffset();
2332 }
2333
2334 if (!ov.queueBuffer(fd, offset, dest)) {
2335 ALOGE("%s: queueBuffer failed for display:%d ",
2336 __FUNCTION__, mDpy);
2337 return false;
2338 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002339 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002340
2341 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002342 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002343 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002344}
2345
Saurabh Shah88e4d272013-09-03 13:31:29 -07002346//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002347
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002348void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302349 hwc_display_contents_1_t* list){
2350 //if 4kx2k yuv layer is totally present in either in left half
2351 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302352 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302353 if(mCurrentFrame.fbZ >= 0) {
2354 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2355 index++) {
2356 if(!mCurrentFrame.isFBComposed[index]) {
2357 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2358 mdpNextZOrder++;
2359 }
2360 mdpNextZOrder++;
2361 hwc_layer_1_t* layer = &list->hwLayers[index];
2362 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302363 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302364 hwc_rect_t dst = layer->displayFrame;
2365 if((dst.left > lSplit) || (dst.right < lSplit)) {
2366 mCurrentFrame.mdpCount += 1;
2367 }
2368 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2369 mCurrentFrame.fbZ += 1;
2370 mdpNextZOrder++;
2371 }
2372 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002373 }
radhakrishnac9a67412013-09-25 17:40:42 +05302374 }
2375}
2376
Saurabh Shah88e4d272013-09-03 13:31:29 -07002377bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002378 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002379
Saurabh Shahc62f3982014-03-05 14:28:26 -08002380 const int lSplit = getLeftSplit(ctx, mDpy);
2381 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002382 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002383 pipe_info.lIndex = ovutils::OV_INVALID;
2384 pipe_info.rIndex = ovutils::OV_INVALID;
2385
Saurabh Shahc62f3982014-03-05 14:28:26 -08002386 Overlay::PipeSpecs pipeSpecs;
2387 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2388 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2389 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2390 pipeSpecs.dpy = mDpy;
2391 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2392 pipeSpecs.fb = false;
2393
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002394 // Acquire pipe only for the updating half
2395 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2396 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2397
2398 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002399 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002400 if(pipe_info.lIndex == ovutils::OV_INVALID)
2401 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002402 }
2403
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002404 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002405 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2406 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002407 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002408 return false;
2409 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002410
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002411 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002412}
2413
Saurabh Shah88e4d272013-09-03 13:31:29 -07002414bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002415 hwc_display_contents_1_t* list) {
2416 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002417
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002418 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002419
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002420 hwc_layer_1_t* layer = &list->hwLayers[index];
2421 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302422 hwc_rect_t dst = layer->displayFrame;
2423 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302424 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302425 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002426 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302427 continue;
2428 }
2429 }
2430 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002431 int mdpIndex = mCurrentFrame.layerToMDP[index];
2432 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002433 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002434 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002435 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002436
Saurabh Shahc62f3982014-03-05 14:28:26 -08002437 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2438 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2439 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002440 return false;
2441 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002442 }
2443 return true;
2444}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002445
radhakrishnac9a67412013-09-25 17:40:42 +05302446int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2447 PipeLayerPair& PipeLayerPair) {
2448 const int lSplit = getLeftSplit(ctx, mDpy);
2449 hwc_rect_t dst = layer->displayFrame;
2450 if((dst.left > lSplit)||(dst.right < lSplit)){
2451 MdpYUVPipeInfo& mdp_info =
2452 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2453 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302454 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302455 eDest lDest = mdp_info.lIndex;
2456 eDest rDest = mdp_info.rIndex;
2457
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002458 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302459 lDest, rDest, &PipeLayerPair.rot);
2460 }
2461 else{
2462 return configure(ctx, layer, PipeLayerPair);
2463 }
2464}
2465
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002466/*
2467 * Configures pipe(s) for MDP composition
2468 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002469int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002470 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002471 MdpPipeInfoSplit& mdp_info =
2472 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002473 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302474 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002475 eDest lDest = mdp_info.lIndex;
2476 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002477
2478 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002479 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002480
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002481 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002482 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002483}
2484
Saurabh Shah88e4d272013-09-03 13:31:29 -07002485bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002486
Raj Kamal4393eaa2014-06-06 13:45:20 +05302487 if(!isEnabled() or !mModeOn) {
2488 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302489 return true;
2490 }
2491
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002492 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002493 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002494 sHandleTimeout = true;
2495 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002496
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002497 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002498 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002499
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002500 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2501 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002502 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002503 if(mCurrentFrame.isFBComposed[i]) continue;
2504
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002505 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002506 private_handle_t *hnd = (private_handle_t *)layer->handle;
2507 if(!hnd) {
2508 ALOGE("%s handle null", __FUNCTION__);
2509 return false;
2510 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002511
2512 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2513 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002514 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002515
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002516 int mdpIndex = mCurrentFrame.layerToMDP[i];
2517
Raj Kamal389d6e32014-08-04 14:43:24 +05302518 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302519 {
2520 MdpYUVPipeInfo& pipe_info =
2521 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2522 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2523 ovutils::eDest indexL = pipe_info.lIndex;
2524 ovutils::eDest indexR = pipe_info.rIndex;
2525 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302526 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302527 if(rot) {
2528 rot->queueBuffer(fd, offset);
2529 fd = rot->getDstMemId();
2530 offset = rot->getDstOffset();
2531 }
2532 if(indexL != ovutils::OV_INVALID) {
2533 ovutils::eDest destL = (ovutils::eDest)indexL;
2534 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2535 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2536 if (!ov.queueBuffer(fd, offset, destL)) {
2537 ALOGE("%s: queueBuffer failed for display:%d",
2538 __FUNCTION__, mDpy);
2539 return false;
2540 }
2541 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002542
radhakrishnac9a67412013-09-25 17:40:42 +05302543 if(indexR != ovutils::OV_INVALID) {
2544 ovutils::eDest destR = (ovutils::eDest)indexR;
2545 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2546 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2547 if (!ov.queueBuffer(fd, offset, destR)) {
2548 ALOGE("%s: queueBuffer failed for display:%d",
2549 __FUNCTION__, mDpy);
2550 return false;
2551 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002552 }
2553 }
radhakrishnac9a67412013-09-25 17:40:42 +05302554 else{
2555 MdpPipeInfoSplit& pipe_info =
2556 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2557 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002558
radhakrishnac9a67412013-09-25 17:40:42 +05302559 ovutils::eDest indexL = pipe_info.lIndex;
2560 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002561
radhakrishnac9a67412013-09-25 17:40:42 +05302562 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002563 uint32_t offset = (uint32_t)hnd->offset;
2564 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2565 if (!mDpy && (index != -1)) {
2566 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2567 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002568 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002569 }
radhakrishnac9a67412013-09-25 17:40:42 +05302570
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002571 if(ctx->mAD->draw(ctx, fd, offset)) {
2572 fd = ctx->mAD->getDstFd();
2573 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002574 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002575
radhakrishnac9a67412013-09-25 17:40:42 +05302576 if(rot) {
2577 rot->queueBuffer(fd, offset);
2578 fd = rot->getDstMemId();
2579 offset = rot->getDstOffset();
2580 }
2581
2582 //************* play left mixer **********
2583 if(indexL != ovutils::OV_INVALID) {
2584 ovutils::eDest destL = (ovutils::eDest)indexL;
2585 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2586 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2587 if (!ov.queueBuffer(fd, offset, destL)) {
2588 ALOGE("%s: queueBuffer failed for left mixer",
2589 __FUNCTION__);
2590 return false;
2591 }
2592 }
2593
2594 //************* play right mixer **********
2595 if(indexR != ovutils::OV_INVALID) {
2596 ovutils::eDest destR = (ovutils::eDest)indexR;
2597 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2598 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2599 if (!ov.queueBuffer(fd, offset, destR)) {
2600 ALOGE("%s: queueBuffer failed for right mixer",
2601 __FUNCTION__);
2602 return false;
2603 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002604 }
2605 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002606
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002607 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2608 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002609
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002610 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002611}
Saurabh Shahab47c692014-02-12 18:45:57 -08002612
2613//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002614
2615bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2616 hwc_display_contents_1_t* list) {
2617 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2618 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2619
2620 for(int i = numAppLayers - 1; i >= 0; i--) {
2621 if(!isValidRect(visibleRect)) {
2622 mCurrentFrame.drop[i] = true;
2623 mCurrentFrame.dropCount++;
2624 continue;
2625 }
2626
2627 const hwc_layer_1_t* layer = &list->hwLayers[i];
2628 hwc_rect_t dstRect = layer->displayFrame;
2629 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2630
2631 if(!isValidRect(res)) {
2632 mCurrentFrame.drop[i] = true;
2633 mCurrentFrame.dropCount++;
2634 } else {
2635 /* Reset frame ROI when any layer which needs scaling also needs ROI
2636 * cropping */
2637 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2638 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2639 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2640 mCurrentFrame.dropCount = 0;
2641 return false;
2642 }
2643
2644 /* deduct any opaque region from visibleRect */
2645 if (layer->blending == HWC_BLENDING_NONE &&
2646 layer->planeAlpha == 0xFF)
2647 visibleRect = deductRect(visibleRect, res);
2648 }
2649 }
2650 return true;
2651}
2652
2653/*
2654 * HW Limitation: ping pong split can always split the ping pong output
2655 * equally across two DSI's. So the ROI programmed should be of equal width
2656 * for both the halves
2657 */
2658void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2659 hwc_display_contents_1_t* list) {
2660 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2661
2662
2663 if(!canPartialUpdate(ctx, list))
2664 return;
2665
2666 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2667 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2668 (int)ctx->dpyAttr[mDpy].yres};
2669
2670 for(int index = 0; index < numAppLayers; index++ ) {
2671 hwc_layer_1_t* layer = &list->hwLayers[index];
2672
2673 // If we have a RGB layer which needs rotation, no partial update
2674 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2675 return;
2676
2677 if ((mCachedFrame.hnd[index] != layer->handle) ||
2678 isYuvBuffer((private_handle_t *)layer->handle)) {
2679 hwc_rect_t dst = layer->displayFrame;
2680 hwc_rect_t updatingRect = dst;
2681
2682#ifdef QCOM_BSP
2683 if(!needsScaling(layer) && !layer->transform)
2684 {
2685 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2686 int x_off = dst.left - src.left;
2687 int y_off = dst.top - src.top;
2688 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2689 }
2690#endif
2691
2692 roi = getUnion(roi, updatingRect);
2693 }
2694 }
2695
2696 /* No layer is updating. Still SF wants a refresh.*/
2697 if(!isValidRect(roi))
2698 return;
2699
2700 roi = expandROIFromMidPoint(roi, fullFrame);
2701
2702 hwc_rect lFrame = fullFrame;
2703 lFrame.right /= 2;
2704 hwc_rect lRoi = getIntersection(roi, lFrame);
2705
2706 // Align ROI coordinates to panel restrictions
2707 lRoi = getSanitizeROI(lRoi, lFrame);
2708
2709 hwc_rect rFrame = fullFrame;
2710 rFrame.left = lFrame.right;
2711 hwc_rect rRoi = getIntersection(roi, rFrame);
2712
2713 // Align ROI coordinates to panel restrictions
2714 rRoi = getSanitizeROI(rRoi, rFrame);
2715
2716 roi = getUnion(lRoi, rRoi);
2717
2718 ctx->listStats[mDpy].lRoi = roi;
2719 if(!validateAndApplyROI(ctx, list))
2720 resetROI(ctx, mDpy);
2721
2722 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2723 __FUNCTION__,
2724 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2725 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2726 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2727 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2728}
2729
Saurabh Shahab47c692014-02-12 18:45:57 -08002730bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002731 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002732 private_handle_t *hnd = (private_handle_t *)layer->handle;
2733 hwc_rect_t dst = layer->displayFrame;
2734 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2735 pipe_info.lIndex = ovutils::OV_INVALID;
2736 pipe_info.rIndex = ovutils::OV_INVALID;
2737
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002738 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2739 trimAgainstROI(ctx,crop, dst);
2740
Saurabh Shahab47c692014-02-12 18:45:57 -08002741 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2742 //should have a higher priority than the right one. Pipe priorities are
2743 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002744
Saurabh Shahc62f3982014-03-05 14:28:26 -08002745 Overlay::PipeSpecs pipeSpecs;
2746 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2747 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2748 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2749 pipeSpecs.dpy = mDpy;
2750 pipeSpecs.fb = false;
2751
Saurabh Shahab47c692014-02-12 18:45:57 -08002752 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002753 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002754 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002755 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002756 }
2757
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002758 /* Use 2 pipes IF
2759 a) Layer's crop width is > 2048 or
2760 b) Layer's dest width > 2048 or
2761 c) On primary, driver has indicated with caps to split always. This is
2762 based on an empirically derived value of panel height. Applied only
2763 if the layer's width is > mixer's width
2764 */
2765
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302766 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002767 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302768 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002769 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2770 const uint32_t dstWidth = dst.right - dst.left;
2771 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002772 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002773 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002774 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002775 crop.bottom - crop.top;
2776 //Approximation to actual clock, ignoring the common factors in pipe and
2777 //mixer cases like line_time
2778 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2779 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002780
Saurabh Shah05f4e222015-02-05 14:36:22 -08002781 const uint32_t downscale = getRotDownscale(ctx, layer);
2782 if(downscale) {
2783 cropWidth /= downscale;
2784 cropHeight /= downscale;
2785 }
2786
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002787 if(dstWidth > mdpHw.getMaxPipeWidth() or
2788 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002789 (primarySplitAlways and
2790 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002791 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002792 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002793 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002794 }
2795
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002796 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2797 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002798 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002799 }
2800 }
2801
2802 return true;
2803}
2804
Saurabh Shahab47c692014-02-12 18:45:57 -08002805int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2806 PipeLayerPair& PipeLayerPair) {
2807 private_handle_t *hnd = (private_handle_t *)layer->handle;
2808 if(!hnd) {
2809 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2810 return -1;
2811 }
2812 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2813 MdpPipeInfoSplit& mdp_info =
2814 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2815 Rotator **rot = &PipeLayerPair.rot;
2816 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002817 eDest lDest = mdp_info.lIndex;
2818 eDest rDest = mdp_info.rIndex;
2819 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2820 hwc_rect_t dst = layer->displayFrame;
2821 int transform = layer->transform;
2822 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002823 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002824 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002825 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2826
2827 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2828 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2829
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002830 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2831 /* MDP driver crops layer coordinates against ROI in Non-Split
2832 * and Split MDP comp. But HWC needs to crop them for source split.
2833 * Reason: 1) Source split is efficient only when the final effective
2834 * load is distributed evenly across mixers.
2835 * 2) We have to know the effective width of the layer that
2836 * the ROI needs to find the no. of pipes the layer needs.
2837 */
2838 trimAgainstROI(ctx, crop, dst);
2839 }
2840
Saurabh Shahab47c692014-02-12 18:45:57 -08002841 // Handle R/B swap
2842 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2843 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2844 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2845 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2846 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2847 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002848 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002849 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2850 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002851 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002852 /* Calculate the external display position based on MDP downscale,
2853 ActionSafe, and extorientation features. */
2854 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002855
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002856 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302857 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002858 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002859
2860 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2861 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002862 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002863 }
2864
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002865 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002866 (*rot) = ctx->mRotMgr->getNext();
2867 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002868 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002869 //If the video is using a single pipe, enable BWC
2870 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002871 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2872 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002873 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002874 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002875 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002876 ALOGE("%s: configRotator failed!", __FUNCTION__);
2877 return -1;
2878 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002879 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002880 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002881 }
2882
2883 //If 2 pipes being used, divide layer into half, crop and dst
2884 hwc_rect_t cropL = crop;
2885 hwc_rect_t cropR = crop;
2886 hwc_rect_t dstL = dst;
2887 hwc_rect_t dstR = dst;
2888 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2889 cropL.right = (crop.right + crop.left) / 2;
2890 cropR.left = cropL.right;
2891 sanitizeSourceCrop(cropL, cropR, hnd);
2892
Saurabh Shahb729b192014-08-15 18:04:24 -07002893 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002894 //Swap crops on H flip since 2 pipes are being used
2895 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2896 hwc_rect_t tmp = cropL;
2897 cropL = cropR;
2898 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002899 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002900 }
2901
Saurabh Shahb729b192014-08-15 18:04:24 -07002902 //cropSwap trick: If the src and dst widths are both odd, let us say
2903 //2507, then splitting both into half would cause left width to be 1253
2904 //and right 1254. If crop is swapped because of H flip, this will cause
2905 //left crop width to be 1254, whereas left dst width remains 1253, thus
2906 //inducing a scaling that is unaccounted for. To overcome that we add 1
2907 //to the dst width if there is a cropSwap. So if the original width was
2908 //2507, the left dst width will be 1254. Even if the original width was
2909 //even for ex: 2508, the left dst width will still remain 1254.
2910 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002911 dstR.left = dstL.right;
2912 }
2913
2914 //For the mdp, since either we are pre-rotating or MDP does flips
2915 orient = OVERLAY_TRANSFORM_0;
2916 transform = 0;
2917
2918 //configure left pipe
2919 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002920 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002921 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2922 (ovutils::eBlending) getBlending(layer->blending));
2923
2924 if(configMdp(ctx->mOverlay, pargL, orient,
2925 cropL, dstL, metadata, lDest) < 0) {
2926 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2927 return -1;
2928 }
2929 }
2930
2931 //configure right pipe
2932 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002933 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002934 static_cast<eRotFlags>(rotFlags),
2935 layer->planeAlpha,
2936 (ovutils::eBlending) getBlending(layer->blending));
2937 if(configMdp(ctx->mOverlay, pargR, orient,
2938 cropR, dstR, metadata, rDest) < 0) {
2939 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2940 return -1;
2941 }
2942 }
2943
2944 return 0;
2945}
2946
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002947bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2948 Locker::Autolock _l(ctx->mDrawLock);
2949 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2950 char path[MAX_SYSFS_FILE_PATH];
2951 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2952 int fd = open(path, O_RDONLY);
2953 if(fd < 0) {
2954 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2955 return -1;
2956 }
2957 char value[4];
2958 ssize_t size_read = read(fd, value, sizeof(value)-1);
2959 if(size_read <= 0) {
2960 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2961 close(fd);
2962 return -1;
2963 }
2964 close(fd);
2965 value[size_read] = '\0';
2966 return atoi(value);
2967}
2968
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002969int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2970 Locker::Autolock _l(ctx->mDrawLock);
2971 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2972 char path[MAX_SYSFS_FILE_PATH];
2973 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2974 int fd = open(path, O_WRONLY);
2975 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002976 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002977 return -1;
2978 }
2979 char value[4];
2980 snprintf(value, sizeof(value), "%d", (int)enable);
2981 ssize_t ret = write(fd, value, strlen(value));
2982 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002983 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002984 close(fd);
2985 return -1;
2986 }
2987 close(fd);
2988 sIsPartialUpdateActive = enable;
2989 return 0;
2990}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002991
2992bool MDPComp::loadPerfLib() {
2993 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2994 bool success = false;
2995 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2996 ALOGE("vendor library not set in ro.vendor.extension_library");
2997 return false;
2998 }
2999
3000 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3001 if(sLibPerfHint) {
3002 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3003 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3004 if (!sPerfLockAcquire || !sPerfLockRelease) {
3005 ALOGE("Failed to load symbols for perfLock");
3006 dlclose(sLibPerfHint);
3007 sLibPerfHint = NULL;
3008 return false;
3009 }
3010 success = true;
3011 ALOGI("Successfully Loaded perf hint API's");
3012 } else {
3013 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3014 }
3015 return success;
3016}
3017
3018void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3019 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3020 return;
3021 }
3022 static int count = sPerfHintWindow;
3023 static int perflockFlag = 0;
3024
3025 /* Send hint to mpctl when single layer is updated
3026 * for a successful number of windows. Hint release
3027 * happens immediately upon multiple layer update.
3028 */
3029 if (onlyVideosUpdating(ctx, list)) {
3030 if(count) {
3031 count--;
3032 }
3033 } else {
3034 if (perflockFlag) {
3035 perflockFlag = 0;
3036 sPerfLockRelease(sPerfLockHandle);
3037 }
3038 count = sPerfHintWindow;
3039 }
3040 if (count == 0 && !perflockFlag) {
3041 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3042 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3043 &perfHint, sizeof(perfHint)/sizeof(int));
3044 if(sPerfLockHandle < 0) {
3045 ALOGE("Perf Lock Acquire Failed");
3046 } else {
3047 perflockFlag = 1;
3048 }
3049 }
3050}
3051
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003052}; //namespace
3053