blob: 2d6497e4bbf9d9c691f79f8fc13cda52c296015d [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
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500806 // No MDP composition for 3D
807 if(needs3DComposition(ctx, mDpy))
808 return false;
809
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700810 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800811 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700812 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800813 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
814 return false;
815 }
816
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800817 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800818 hwc_layer_1_t* layer = &list->hwLayers[i];
819 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800820
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800821 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700822 if(!canUseRotator(ctx, mDpy)) {
823 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
824 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700825 return false;
826 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800827 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530828
829 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
830 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800831 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700832 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530833 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
834 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
835 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800836 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700837
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700838 if(ctx->mAD->isDoable()) {
839 return false;
840 }
841
Saurabh Shahaa236822013-04-24 18:07:26 -0700842 //If all above hard conditions are met we can do full or partial MDP comp.
843 bool ret = false;
844 if(fullMDPComp(ctx, list)) {
845 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700846 } else if(fullMDPCompWithPTOR(ctx, list)) {
847 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700848 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700849 ret = true;
850 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530851
Saurabh Shahaa236822013-04-24 18:07:26 -0700852 return ret;
853}
854
855bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700856
857 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
858 return false;
859
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700860 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
861 for(int i = 0; i < numAppLayers; i++) {
862 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700863 if(not mCurrentFrame.drop[i] and
864 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700865 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
866 return false;
867 }
868 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800869
Saurabh Shahaa236822013-04-24 18:07:26 -0700870 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700871 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
872 sizeof(mCurrentFrame.isFBComposed));
873 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
874 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700875
Raj Kamal389d6e32014-08-04 14:43:24 +0530876 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800877 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530878 }
879
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800880 if(!postHeuristicsHandling(ctx, list)) {
881 ALOGD_IF(isDebug(), "post heuristic handling failed");
882 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700883 return false;
884 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700885 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
886 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700887 return true;
888}
889
Sushil Chauhandefd3522014-05-13 18:17:12 -0700890/* Full MDP Composition with Peripheral Tiny Overlap Removal.
891 * MDP bandwidth limitations can be avoided, if the overlap region
892 * covered by the smallest layer at a higher z-order, gets composed
893 * by Copybit on a render buffer, which can be queued to MDP.
894 */
895bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
896 hwc_display_contents_1_t* list) {
897
898 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
899 const int stagesForMDP = min(sMaxPipesPerMixer,
900 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
901
902 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700903 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700904 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
905 return false;
906 }
907
908 // Frame level checks
909 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
910 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
911 isSecurePresent(ctx, mDpy)) {
912 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
913 return false;
914 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700915 // MDP comp checks
916 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700917 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 if(not isSupportedForMDPComp(ctx, layer)) {
919 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
920 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700921 }
922 }
923
Sushil Chauhandefd3522014-05-13 18:17:12 -0700924 /* We cannot use this composition mode, if:
925 1. A below layer needs scaling.
926 2. Overlap is not peripheral to display.
927 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700928 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700929 */
930
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700931 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
932 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
933 memset(overlapRect, 0, sizeof(overlapRect));
934 int layerPixelCount, minPixelCount = 0;
935 int numPTORLayersFound = 0;
936 for (int i = numAppLayers-1; (i >= 0 &&
937 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700938 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700939 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700940 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700941 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
942 // PTOR layer should be peripheral and cannot have transform
943 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
944 has90Transform(layer)) {
945 continue;
946 }
947 if((3 * (layerPixelCount + minPixelCount)) >
948 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
949 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
950 continue;
951 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700952 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700953 for (int j = i-1; j >= 0; j--) {
954 // Check if the layers below this layer qualifies for PTOR comp
955 hwc_layer_1_t* layer = &list->hwLayers[j];
956 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700957 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700958 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700959 if (isValidRect(getIntersection(dispFrame, disFrame))) {
960 if (has90Transform(layer) || needsScaling(layer)) {
961 found = false;
962 break;
963 }
964 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700965 }
966 }
967 // Store the minLayer Index
968 if(found) {
969 minLayerIndex[numPTORLayersFound] = i;
970 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
971 minPixelCount += layerPixelCount;
972 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700973 }
974 }
975
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700976 // No overlap layers
977 if (!numPTORLayersFound)
978 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700979
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700980 // Store the displayFrame and the sourceCrops of the layers
981 hwc_rect_t displayFrame[numAppLayers];
982 hwc_rect_t sourceCrop[numAppLayers];
983 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700984 hwc_layer_1_t* layer = &list->hwLayers[i];
985 displayFrame[i] = layer->displayFrame;
986 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700987 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700988
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530989 /**
990 * It's possible that 2 PTOR layers might have overlapping.
991 * In such case, remove the intersection(again if peripheral)
992 * from the lower PTOR layer to avoid overlapping.
993 * If intersection is not on peripheral then compromise
994 * by reducing number of PTOR layers.
995 **/
996 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
997 if(isValidRect(commonRect)) {
998 overlapRect[1] = deductRect(overlapRect[1], commonRect);
999 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1000 }
1001
1002 ctx->mPtorInfo.count = numPTORLayersFound;
1003 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1004 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1005 }
1006
1007 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1008 // reset PTOR
1009 ctx->mPtorInfo.count = 0;
1010 if(isValidRect(commonRect)) {
1011 // If PTORs are intersecting restore displayframe of PTOR[1]
1012 // before returning, as we have modified it above.
1013 list->hwLayers[minLayerIndex[1]].displayFrame =
1014 displayFrame[minLayerIndex[1]];
1015 }
1016 return false;
1017 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001018 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1019 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1020
Xu Yangcda012c2014-07-30 21:57:21 +08001021 // Store the blending mode, planeAlpha, and transform of PTOR layers
1022 int32_t blending[numPTORLayersFound];
1023 uint8_t planeAlpha[numPTORLayersFound];
1024 uint32_t transform[numPTORLayersFound];
1025
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001026 for(int j = 0; j < numPTORLayersFound; j++) {
1027 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001028
1029 // Update src crop of PTOR layer
1030 hwc_layer_1_t* layer = &list->hwLayers[index];
1031 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1032 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1033 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1034 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1035
1036 // Store & update w, h, format of PTOR layer
1037 private_handle_t *hnd = (private_handle_t *)layer->handle;
1038 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1039 layerWhf[j] = whf;
1040 hnd->width = renderBuf->width;
1041 hnd->height = renderBuf->height;
1042 hnd->format = renderBuf->format;
1043
Xu Yangcda012c2014-07-30 21:57:21 +08001044 // Store & update blending mode, planeAlpha and transform of PTOR layer
1045 blending[j] = layer->blending;
1046 planeAlpha[j] = layer->planeAlpha;
1047 transform[j] = layer->transform;
1048 layer->blending = HWC_BLENDING_NONE;
1049 layer->planeAlpha = 0xFF;
1050 layer->transform = 0;
1051
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001052 // Remove overlap from crop & displayFrame of below layers
1053 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001054 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001055 if(!isValidRect(getIntersection(layer->displayFrame,
1056 overlapRect[j]))) {
1057 continue;
1058 }
1059 // Update layer attributes
1060 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1061 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301062 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001063 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1064 layer->transform);
1065 layer->sourceCropf.left = (float)srcCrop.left;
1066 layer->sourceCropf.top = (float)srcCrop.top;
1067 layer->sourceCropf.right = (float)srcCrop.right;
1068 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1069 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001070 }
1071
1072 mCurrentFrame.mdpCount = numAppLayers;
1073 mCurrentFrame.fbCount = 0;
1074 mCurrentFrame.fbZ = -1;
1075
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301076 for (int j = 0; j < numAppLayers; j++) {
1077 if(isValidRect(list->hwLayers[j].displayFrame)) {
1078 mCurrentFrame.isFBComposed[j] = false;
1079 } else {
1080 mCurrentFrame.mdpCount--;
1081 mCurrentFrame.drop[j] = true;
1082 }
1083 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001084
1085 bool result = postHeuristicsHandling(ctx, list);
1086
1087 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001088 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001089 hwc_layer_1_t* layer = &list->hwLayers[i];
1090 layer->displayFrame = displayFrame[i];
1091 layer->sourceCropf.left = (float)sourceCrop[i].left;
1092 layer->sourceCropf.top = (float)sourceCrop[i].top;
1093 layer->sourceCropf.right = (float)sourceCrop[i].right;
1094 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1095 }
1096
Xu Yangcda012c2014-07-30 21:57:21 +08001097 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001098 for (int i = 0; i < numPTORLayersFound; i++) {
1099 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001100 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001101 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1102 hnd->width = layerWhf[i].w;
1103 hnd->height = layerWhf[i].h;
1104 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001105 layer->blending = blending[i];
1106 layer->planeAlpha = planeAlpha[i];
1107 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001108 }
1109
Sushil Chauhandefd3522014-05-13 18:17:12 -07001110 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001111 // reset PTOR
1112 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001113 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001114 } else {
1115 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1116 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001117 }
1118
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001119 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1120 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001121 return result;
1122}
1123
Saurabh Shahaa236822013-04-24 18:07:26 -07001124bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1125{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001126 if(!sEnableMixedMode) {
1127 //Mixed mode is disabled. No need to even try caching.
1128 return false;
1129 }
1130
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001131 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301132 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1133 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001134 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001135 cacheBasedComp(ctx, list);
1136 } else {
1137 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001138 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001139 }
1140
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001141 return ret;
1142}
1143
1144bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1145 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001146 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1147 return false;
1148
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001149 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001150 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001151 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001152
1153 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1154 for(int i = 0; i < numAppLayers; i++) {
1155 if(!mCurrentFrame.isFBComposed[i]) {
1156 hwc_layer_1_t* layer = &list->hwLayers[i];
1157 if(not isSupportedForMDPComp(ctx, layer)) {
1158 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1159 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001160 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001161 return false;
1162 }
1163 }
1164 }
1165
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001166 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001167 /* mark secure RGB layers for MDP comp */
1168 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301169 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001170 if(!ret) {
1171 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001172 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001173 return false;
1174 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001175
1176 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001177
Raj Kamal389d6e32014-08-04 14:43:24 +05301178 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001179 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301180 }
1181
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001182 if(!postHeuristicsHandling(ctx, list)) {
1183 ALOGD_IF(isDebug(), "post heuristic handling failed");
1184 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001185 return false;
1186 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001187 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1188 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001189
Saurabh Shahaa236822013-04-24 18:07:26 -07001190 return true;
1191}
1192
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001193bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001194 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001195 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1196 return false;
1197
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001198 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001199 return false;
1200 }
1201
Saurabh Shahb772ae32013-11-18 15:40:02 -08001202 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001203 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1204 const int stagesForMDP = min(sMaxPipesPerMixer,
1205 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001206
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001207 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1208 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1209 int lastMDPSupportedIndex = numAppLayers;
1210 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001211
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001212 //Find the minimum MDP batch size
1213 for(int i = 0; i < numAppLayers;i++) {
1214 if(mCurrentFrame.drop[i]) {
1215 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001216 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001217 }
1218 hwc_layer_1_t* layer = &list->hwLayers[i];
1219 if(not isSupportedForMDPComp(ctx, layer)) {
1220 lastMDPSupportedIndex = i;
1221 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1222 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001223 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001224 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001225 }
1226
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001227 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1228 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1229 mCurrentFrame.dropCount);
1230
1231 //Start at a point where the fb batch should at least have 2 layers, for
1232 //this mode to be justified.
1233 while(fbBatchSize < 2) {
1234 ++fbBatchSize;
1235 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001236 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001237
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001238 //If there are no layers for MDP, this mode doesnt make sense.
1239 if(mdpBatchSize < 1) {
1240 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1241 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001242 return false;
1243 }
1244
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001245 mCurrentFrame.reset(numAppLayers);
1246
1247 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1248 while(mdpBatchSize > 0) {
1249 //Mark layers for MDP comp
1250 int mdpBatchLeft = mdpBatchSize;
1251 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1252 if(mCurrentFrame.drop[i]) {
1253 continue;
1254 }
1255 mCurrentFrame.isFBComposed[i] = false;
1256 --mdpBatchLeft;
1257 }
1258
1259 mCurrentFrame.fbZ = mdpBatchSize;
1260 mCurrentFrame.fbCount = fbBatchSize;
1261 mCurrentFrame.mdpCount = mdpBatchSize;
1262
1263 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1264 __FUNCTION__, mdpBatchSize, fbBatchSize,
1265 mCurrentFrame.dropCount);
1266
1267 if(postHeuristicsHandling(ctx, list)) {
1268 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001269 __FUNCTION__);
1270 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1271 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001272 return true;
1273 }
1274
1275 reset(ctx);
1276 --mdpBatchSize;
1277 ++fbBatchSize;
1278 }
1279
1280 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001281}
1282
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001283bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301284 if(mDpy or isSecurePresent(ctx, mDpy) or
1285 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001286 return false;
1287 }
1288 return true;
1289}
1290
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001291bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1292 hwc_display_contents_1_t* list){
1293 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1294 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001295 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001296 return false;
1297 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001298 if(ctx->listStats[mDpy].secureUI)
1299 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001300 return true;
1301}
1302
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001303bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1304 hwc_display_contents_1_t* list) {
1305 const bool secureOnly = true;
1306 return videoOnlyComp(ctx, list, not secureOnly) or
1307 videoOnlyComp(ctx, list, secureOnly);
1308}
1309
1310bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001311 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001312 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1313 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301314
Saurabh Shahaa236822013-04-24 18:07:26 -07001315 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301316 if(!isSecurePresent(ctx, mDpy)) {
1317 /* Bail out if we are processing only secured video layers
1318 * and we dont have any */
1319 if(secureOnly) {
1320 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1321 return false;
1322 }
1323 /* No Idle fall back for secure video layers and if there is only
1324 * single layer being composed. */
1325 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1326 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1327 return false;
1328 }
1329 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001330
Saurabh Shahaa236822013-04-24 18:07:26 -07001331 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001332 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001333 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001334 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001335
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001336 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1337 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001338 return false;
1339 }
1340
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001341 if(mCurrentFrame.fbCount)
1342 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001343
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001344 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001345 adjustForSourceSplit(ctx, list);
1346 }
1347
1348 if(!postHeuristicsHandling(ctx, list)) {
1349 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301350 if(errno == ENOBUFS) {
1351 ALOGD_IF(isDebug(), "SMP Allocation failed");
1352 //On SMP allocation failure in video only comp add padding round
1353 ctx->isPaddingRound = true;
1354 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001355 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001356 return false;
1357 }
1358
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001359 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1360 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001361 return true;
1362}
1363
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001364/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1365bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1366 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001367 // Fall back to video only composition, if AIV video mode is enabled
1368 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001369 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1370 __FUNCTION__, mDpy);
1371 return false;
1372 }
1373
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001374 // No MDP composition for 3D
1375 if(needs3DComposition(ctx,mDpy))
1376 return false;
1377
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001378 const bool secureOnly = true;
1379 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1380 mdpOnlyLayersComp(ctx, list, secureOnly);
1381
1382}
1383
1384bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1385 hwc_display_contents_1_t* list, bool secureOnly) {
1386
1387 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1388 return false;
1389
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301390 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1391 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1392 /* Bail out if we are processing only secured video/ui layers
1393 * and we dont have any */
1394 if(secureOnly) {
1395 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1396 return false;
1397 }
1398 /* No Idle fall back for secure video/ui layers and if there is only
1399 * single layer being composed. */
1400 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1401 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1402 return false;
1403 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001404 }
1405
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001406 /* Bail out if we dont have any secure RGB layers */
1407 if (!ctx->listStats[mDpy].secureRGBCount) {
1408 reset(ctx);
1409 return false;
1410 }
1411
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001412 mCurrentFrame.reset(numAppLayers);
1413 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1414
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001415 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001416 /* mark secure RGB layers for MDP comp */
1417 updateSecureRGB(ctx, list);
1418
1419 if(mCurrentFrame.mdpCount == 0) {
1420 reset(ctx);
1421 return false;
1422 }
1423
1424 /* find the maximum batch of layers to be marked for framebuffer */
1425 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1426 if(!ret) {
1427 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1428 reset(ctx);
1429 return false;
1430 }
1431
1432 if(sEnableYUVsplit){
1433 adjustForSourceSplit(ctx, list);
1434 }
1435
1436 if(!postHeuristicsHandling(ctx, list)) {
1437 ALOGD_IF(isDebug(), "post heuristic handling failed");
1438 reset(ctx);
1439 return false;
1440 }
1441
1442 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1443 __FUNCTION__);
1444 return true;
1445}
1446
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001447/* Checks for conditions where YUV layers cannot be bypassed */
1448bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001449 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001450 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001451 return false;
1452 }
1453
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001454 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001455 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1456 return false;
1457 }
1458
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001459 if(isSecuring(ctx, layer)) {
1460 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1461 return false;
1462 }
1463
Saurabh Shah4fdde762013-04-30 18:47:33 -07001464 if(!isValidDimension(ctx, layer)) {
1465 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1466 __FUNCTION__);
1467 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001468 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001469
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001470 if(layer->planeAlpha < 0xFF) {
1471 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1472 in video only mode",
1473 __FUNCTION__);
1474 return false;
1475 }
1476
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001477 return true;
1478}
1479
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001480/* Checks for conditions where Secure RGB layers cannot be bypassed */
1481bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1482 if(isSkipLayer(layer)) {
1483 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1484 __FUNCTION__, mDpy);
1485 return false;
1486 }
1487
1488 if(isSecuring(ctx, layer)) {
1489 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1490 return false;
1491 }
1492
1493 if(not isSupportedForMDPComp(ctx, layer)) {
1494 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1495 __FUNCTION__);
1496 return false;
1497 }
1498 return true;
1499}
1500
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301501/* starts at fromIndex and check for each layer to find
1502 * if it it has overlapping with any Updating layer above it in zorder
1503 * till the end of the batch. returns true if it finds any intersection */
1504bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1505 int fromIndex, int toIndex) {
1506 for(int i = fromIndex; i < toIndex; i++) {
1507 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1508 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1509 return false;
1510 }
1511 }
1512 }
1513 return true;
1514}
1515
1516/* Checks if given layer at targetLayerIndex has any
1517 * intersection with all the updating layers in beween
1518 * fromIndex and toIndex. Returns true if it finds intersectiion */
1519bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1520 int fromIndex, int toIndex, int targetLayerIndex) {
1521 for(int i = fromIndex; i <= toIndex; i++) {
1522 if(!mCurrentFrame.isFBComposed[i]) {
1523 if(areLayersIntersecting(&list->hwLayers[i],
1524 &list->hwLayers[targetLayerIndex])) {
1525 return true;
1526 }
1527 }
1528 }
1529 return false;
1530}
1531
1532int MDPComp::getBatch(hwc_display_contents_1_t* list,
1533 int& maxBatchStart, int& maxBatchEnd,
1534 int& maxBatchCount) {
1535 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301536 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001537 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301538 while (i < mCurrentFrame.layerCount) {
1539 int batchCount = 0;
1540 int batchStart = i;
1541 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001542 /* Adjust batch Z order with the dropped layers so far */
1543 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301544 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301545 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301546 while(i < mCurrentFrame.layerCount) {
1547 if(!mCurrentFrame.isFBComposed[i]) {
1548 if(!batchCount) {
1549 i++;
1550 break;
1551 }
1552 updatingLayersAbove++;
1553 i++;
1554 continue;
1555 } else {
1556 if(mCurrentFrame.drop[i]) {
1557 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001558 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301559 continue;
1560 } else if(updatingLayersAbove <= 0) {
1561 batchCount++;
1562 batchEnd = i;
1563 i++;
1564 continue;
1565 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1566
1567 // We have a valid updating layer already. If layer-i not
1568 // have overlapping with all updating layers in between
1569 // batch-start and i, then we can add layer i to batch.
1570 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1571 batchCount++;
1572 batchEnd = i;
1573 i++;
1574 continue;
1575 } else if(canPushBatchToTop(list, batchStart, i)) {
1576 //If All the non-updating layers with in this batch
1577 //does not have intersection with the updating layers
1578 //above in z-order, then we can safely move the batch to
1579 //higher z-order. Increment fbZ as it is moving up.
1580 if( firstZReverseIndex < 0) {
1581 firstZReverseIndex = i;
1582 }
1583 batchCount++;
1584 batchEnd = i;
1585 fbZ += updatingLayersAbove;
1586 i++;
1587 updatingLayersAbove = 0;
1588 continue;
1589 } else {
1590 //both failed.start the loop again from here.
1591 if(firstZReverseIndex >= 0) {
1592 i = firstZReverseIndex;
1593 }
1594 break;
1595 }
1596 }
1597 }
1598 }
1599 if(batchCount > maxBatchCount) {
1600 maxBatchCount = batchCount;
1601 maxBatchStart = batchStart;
1602 maxBatchEnd = batchEnd;
1603 fbZOrder = fbZ;
1604 }
1605 }
1606 return fbZOrder;
1607}
1608
1609bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1610 hwc_display_contents_1_t* list) {
1611 /* Idea is to keep as many non-updating(cached) layers in FB and
1612 * send rest of them through MDP. This is done in 2 steps.
1613 * 1. Find the maximum contiguous batch of non-updating layers.
1614 * 2. See if we can improve this batch size for caching by adding
1615 * opaque layers around the batch, if they don't have
1616 * any overlapping with the updating layers in between.
1617 * NEVER mark an updating layer for caching.
1618 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619
1620 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001621 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001622 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301623 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001624
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001625 /* Nothing is cached. No batching needed */
1626 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001627 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001628 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001629
1630 /* No MDP comp layers, try to use other comp modes */
1631 if(mCurrentFrame.mdpCount == 0) {
1632 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001633 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001634
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301635 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001636
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301637 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001638 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001639 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001640 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301641 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001642 if(!mCurrentFrame.drop[i]){
1643 //If an unsupported layer is being attempted to
1644 //be pulled out we should fail
1645 if(not isSupportedForMDPComp(ctx, layer)) {
1646 return false;
1647 }
1648 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001649 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001650 }
1651 }
1652
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301653 // update the frame data
1654 mCurrentFrame.fbZ = fbZ;
1655 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001656 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001657 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658
1659 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301660 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001661
1662 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001663}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001664
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001665void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001666 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001667 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001668 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001669
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 for(int i = 0; i < numAppLayers; i++) {
1671 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001672 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001673 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001674 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001675 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001676 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001677 }
1678 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001679
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001680 frame.fbCount = fbCount;
1681 frame.mdpCount = frame.layerCount - frame.fbCount
1682 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001683
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001684 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1685 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001686}
1687
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001688// drop other non-AIV layers from external display list.
1689void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001690 hwc_display_contents_1_t* list) {
1691 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1692 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001693 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001694 mCurrentFrame.dropCount++;
1695 mCurrentFrame.drop[i] = true;
1696 }
1697 }
1698 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1699 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1700 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1701 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1702 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1703 mCurrentFrame.dropCount);
1704}
1705
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001706void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001707 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001708 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1709 for(int index = 0;index < nYuvCount; index++){
1710 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1711 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1712
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001713 if(mCurrentFrame.drop[nYuvIndex]) {
1714 continue;
1715 }
1716
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001717 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001718 if(!frame.isFBComposed[nYuvIndex]) {
1719 frame.isFBComposed[nYuvIndex] = true;
1720 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001721 }
1722 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001723 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001724 private_handle_t *hnd = (private_handle_t *)layer->handle;
1725 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001726 frame.isFBComposed[nYuvIndex] = false;
1727 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001728 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001729 }
1730 }
1731 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001732
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001733 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1734 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001735}
1736
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001737void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1738 hwc_display_contents_1_t* list) {
1739 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1740 for(int index = 0;index < nSecureRGBCount; index++){
1741 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1742 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1743
1744 if(!isSecureRGBDoable(ctx, layer)) {
1745 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1746 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1747 mCurrentFrame.fbCount++;
1748 }
1749 } else {
1750 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1751 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1752 mCurrentFrame.fbCount--;
1753 }
1754 }
1755 }
1756
1757 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1758 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1759 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1760 mCurrentFrame.fbCount);
1761}
1762
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001763hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1764 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001765 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001766
1767 /* Update only the region of FB needed for composition */
1768 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1769 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1770 hwc_layer_1_t* layer = &list->hwLayers[i];
1771 hwc_rect_t dst = layer->displayFrame;
1772 fbRect = getUnion(fbRect, dst);
1773 }
1774 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001775 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001776 return fbRect;
1777}
1778
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001779bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1780 hwc_display_contents_1_t* list) {
1781
1782 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001783 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001784 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1785 return false;
1786 }
1787
1788 //Limitations checks
1789 if(!hwLimitationsCheck(ctx, list)) {
1790 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1791 return false;
1792 }
1793
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001794 //Configure framebuffer first if applicable
1795 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001796 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001797 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1798 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001799 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1800 __FUNCTION__);
1801 return false;
1802 }
1803 }
1804
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001805 mCurrentFrame.map();
1806
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001807 if(!allocLayerPipes(ctx, list)) {
1808 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001809 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810 }
1811
1812 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001813 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001815 int mdpIndex = mCurrentFrame.layerToMDP[index];
1816 hwc_layer_1_t* layer = &list->hwLayers[index];
1817
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301818 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1819 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1820 mdpNextZOrder++;
1821 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001822 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1823 cur_pipe->zOrder = mdpNextZOrder++;
1824
radhakrishnac9a67412013-09-25 17:40:42 +05301825 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301826 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301827 if(configure4k2kYuv(ctx, layer,
1828 mCurrentFrame.mdpToLayer[mdpIndex])
1829 != 0 ){
1830 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1831 for layer %d",__FUNCTION__, index);
1832 return false;
1833 }
1834 else{
1835 mdpNextZOrder++;
1836 }
1837 continue;
1838 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001839 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1840 mdpNextZOrder++;
1841 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001842 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1843 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301844 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001845 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001846 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001847 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001848 }
1849
Saurabh Shaha36be922013-12-16 18:18:39 -08001850 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1851 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1852 ,__FUNCTION__, mDpy);
1853 return false;
1854 }
1855
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001856 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001857 return true;
1858}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001859
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001860bool MDPComp::resourceCheck(hwc_context_t* ctx,
1861 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001862 const bool fbUsed = mCurrentFrame.fbCount;
1863 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1864 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1865 return false;
1866 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001867
1868 //Will benefit cases where a video has non-updating background.
1869 if((mDpy > HWC_DISPLAY_PRIMARY) and
1870 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1871 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1872 return false;
1873 }
1874
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001875 // Init rotCount to number of rotate sessions used by other displays
1876 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1877 // Count the number of rotator sessions required for current display
1878 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1879 if(!mCurrentFrame.isFBComposed[index]) {
1880 hwc_layer_1_t* layer = &list->hwLayers[index];
1881 private_handle_t *hnd = (private_handle_t *)layer->handle;
1882 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1883 rotCount++;
1884 }
1885 }
1886 }
1887 // if number of layers to rotate exceeds max rotator sessions, bail out.
1888 if(rotCount > RotMgr::MAX_ROT_SESS) {
1889 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1890 __FUNCTION__, mDpy);
1891 return false;
1892 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001893 return true;
1894}
1895
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301896bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1897 hwc_display_contents_1_t* list) {
1898
1899 //A-family hw limitation:
1900 //If a layer need alpha scaling, MDP can not support.
1901 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1902 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1903 if(!mCurrentFrame.isFBComposed[i] &&
1904 isAlphaScaled( &list->hwLayers[i])) {
1905 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1906 return false;
1907 }
1908 }
1909 }
1910
1911 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1912 //If multiple layers requires downscaling and also they are overlapping
1913 //fall back to GPU since MDSS can not handle it.
1914 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1915 qdutils::MDPVersion::getInstance().is8x26()) {
1916 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1917 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1918 if(!mCurrentFrame.isFBComposed[i] &&
1919 isDownscaleRequired(botLayer)) {
1920 //if layer-i is marked for MDP and needs downscaling
1921 //check if any MDP layer on top of i & overlaps with layer-i
1922 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1923 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1924 if(!mCurrentFrame.isFBComposed[j] &&
1925 isDownscaleRequired(topLayer)) {
1926 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1927 topLayer->displayFrame);
1928 if(isValidRect(r))
1929 return false;
1930 }
1931 }
1932 }
1933 }
1934 }
1935 return true;
1936}
1937
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001938// Checks only if videos or single layer(RGB) is updating
1939// which is used for setting dynamic fps or perf hint for single
1940// layer video playback
1941bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1942 hwc_display_contents_1_t* list) {
1943 bool support = false;
1944 FrameInfo frame;
1945 frame.reset(mCurrentFrame.layerCount);
1946 memset(&frame.drop, 0, sizeof(frame.drop));
1947 frame.dropCount = 0;
1948 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1949 updateLayerCache(ctx, list, frame);
1950 updateYUV(ctx, list, false /*secure only*/, frame);
1951 // There are only updating YUV layers or there is single RGB
1952 // Layer(Youtube)
1953 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1954 (frame.layerCount == 1)) {
1955 support = true;
1956 }
1957 return support;
1958}
1959
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301960void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1961 //For primary display, set the dynamic refreshrate
1962 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1963 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301964 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1965 MDPVersion& mdpHw = MDPVersion::getInstance();
1966 if(sIdleFallBack) {
1967 //Set minimum panel refresh rate during idle timeout
1968 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001969 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301970 //Set the new fresh rate, if there is only one updating YUV layer
1971 //or there is one single RGB layer with this request
1972 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1973 }
1974 setRefreshRate(ctx, mDpy, refreshRate);
1975 }
1976}
1977
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001978int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001979 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001980 char property[PROPERTY_VALUE_MAX];
1981
Raj Kamal4393eaa2014-06-06 13:45:20 +05301982 if(!ctx || !list) {
1983 ALOGE("%s: Invalid context or list",__FUNCTION__);
1984 mCachedFrame.reset();
1985 return -1;
1986 }
1987
1988 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001989 if(mDpy == HWC_DISPLAY_PRIMARY) {
1990 sSimulationFlags = 0;
1991 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1992 int currentFlags = atoi(property);
1993 if(currentFlags != sSimulationFlags) {
1994 sSimulationFlags = currentFlags;
1995 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1996 sSimulationFlags, sSimulationFlags);
1997 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001998 }
1999 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002000 // reset PTOR
2001 if(!mDpy)
2002 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002003
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302004 //reset old data
2005 mCurrentFrame.reset(numLayers);
2006 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2007 mCurrentFrame.dropCount = 0;
2008
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302009 //Do not cache the information for next draw cycle.
2010 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2011 ALOGI("%s: Unsupported layer count for mdp composition",
2012 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002013 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302014#ifdef DYNAMIC_FPS
2015 setDynRefreshRate(ctx, list);
2016#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002017 return -1;
2018 }
2019
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002020 // Detect the start of animation and fall back to GPU only once to cache
2021 // all the layers in FB and display FB content untill animation completes.
2022 if(ctx->listStats[mDpy].isDisplayAnimating) {
2023 mCurrentFrame.needsRedraw = false;
2024 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2025 mCurrentFrame.needsRedraw = true;
2026 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2027 }
2028 setMDPCompLayerFlags(ctx, list);
2029 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302030#ifdef DYNAMIC_FPS
2031 setDynRefreshRate(ctx, list);
2032#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002033 ret = -1;
2034 return ret;
2035 } else {
2036 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2037 }
2038
Saurabh Shahb39f8152013-08-22 10:21:44 -07002039 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002040 if(isFrameDoable(ctx)) {
2041 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002042 // if AIV Video mode is enabled, drop all non AIV layers from the
2043 // external display list.
2044 if(ctx->listStats[mDpy].mAIVVideoMode) {
2045 dropNonAIVLayers(ctx, list);
2046 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002047
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002048 // if tryFullFrame fails, try to push all video and secure RGB layers
2049 // to MDP for composition.
2050 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002051 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302052 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002053 setMDPCompLayerFlags(ctx, list);
2054 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002055 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002056 reset(ctx);
2057 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2058 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002059 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002060 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2061 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002062 }
2063 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302064 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2065 enablePartialUpdateForMDP3) {
2066 generateROI(ctx, list);
2067 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2068 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2069 }
2070 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002071 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2072 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002073 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002074 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002075
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002076 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002077 ALOGD("GEOMETRY change: %d",
2078 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002079 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002080 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002081 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002082 }
2083
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002084#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302085 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002086#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002087 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002088
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002089 mCachedFrame.cacheAll(list);
2090 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002091 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002092}
2093
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002094bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302095
2096 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302097 int mdpIndex = mCurrentFrame.layerToMDP[index];
2098 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2099 info.pipeInfo = new MdpYUVPipeInfo;
2100 info.rot = NULL;
2101 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302102
2103 pipe_info.lIndex = ovutils::OV_INVALID;
2104 pipe_info.rIndex = ovutils::OV_INVALID;
2105
Saurabh Shahc62f3982014-03-05 14:28:26 -08002106 Overlay::PipeSpecs pipeSpecs;
2107 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2108 pipeSpecs.needsScaling = true;
2109 pipeSpecs.dpy = mDpy;
2110 pipeSpecs.fb = false;
2111
2112 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302113 if(pipe_info.lIndex == ovutils::OV_INVALID){
2114 bRet = false;
2115 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2116 __FUNCTION__);
2117 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002118 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302119 if(pipe_info.rIndex == ovutils::OV_INVALID){
2120 bRet = false;
2121 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2122 __FUNCTION__);
2123 }
2124 return bRet;
2125}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002126
2127int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2128 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002129 if (ctx->mPtorInfo.isActive()) {
2130 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002131 if (fd < 0) {
2132 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002133 }
2134 }
2135 return fd;
2136}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002137//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002138
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002139void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302140 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002141 //If 4k2k Yuv layer split is possible, and if
2142 //fbz is above 4k2k layer, increment fb zorder by 1
2143 //as we split 4k2k layer and increment zorder for right half
2144 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002145 if(!ctx)
2146 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002147 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302148 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2149 index++) {
2150 if(!mCurrentFrame.isFBComposed[index]) {
2151 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2152 mdpNextZOrder++;
2153 }
2154 mdpNextZOrder++;
2155 hwc_layer_1_t* layer = &list->hwLayers[index];
2156 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302157 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302158 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2159 mCurrentFrame.fbZ += 1;
2160 mdpNextZOrder++;
2161 //As we split 4kx2k yuv layer and program to 2 VG pipes
2162 //(if available) increase mdpcount by 1.
2163 mCurrentFrame.mdpCount++;
2164 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002165 }
2166 }
2167 }
radhakrishnac9a67412013-09-25 17:40:42 +05302168}
2169
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002170/*
2171 * Configures pipe(s) for MDP composition
2172 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002173int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002174 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002175 MdpPipeInfoNonSplit& mdp_info =
2176 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302177 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002178 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002179 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002180
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002181 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2182 __FUNCTION__, layer, zOrder, dest);
2183
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002184 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002185 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002186}
2187
Saurabh Shah88e4d272013-09-03 13:31:29 -07002188bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002189 hwc_display_contents_1_t* list) {
2190 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002191
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002192 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002193
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002194 hwc_layer_1_t* layer = &list->hwLayers[index];
2195 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302196 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002197 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302198 continue;
2199 }
2200 }
2201
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002202 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002203 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002204 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002205 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002206 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002207
Saurabh Shahc62f3982014-03-05 14:28:26 -08002208 Overlay::PipeSpecs pipeSpecs;
2209 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2210 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2211 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2212 (qdutils::MDPVersion::getInstance().is8x26() and
2213 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2214 pipeSpecs.dpy = mDpy;
2215 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002216 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002217
Saurabh Shahc62f3982014-03-05 14:28:26 -08002218 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2219
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002220 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002221 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002222 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002223 }
2224 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002225 return true;
2226}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002227
radhakrishnac9a67412013-09-25 17:40:42 +05302228int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2229 PipeLayerPair& PipeLayerPair) {
2230 MdpYUVPipeInfo& mdp_info =
2231 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2232 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302233 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302234 eDest lDest = mdp_info.lIndex;
2235 eDest rDest = mdp_info.rIndex;
2236
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002237 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302238 lDest, rDest, &PipeLayerPair.rot);
2239}
2240
Saurabh Shah88e4d272013-09-03 13:31:29 -07002241bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002242
Raj Kamal4393eaa2014-06-06 13:45:20 +05302243 if(!isEnabled() or !mModeOn) {
2244 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302245 return true;
2246 }
2247
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002248 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002249 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002250 sHandleTimeout = true;
2251 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002252
2253 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002254 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002255
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002256 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2257 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002258 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002259 if(mCurrentFrame.isFBComposed[i]) continue;
2260
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002261 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002262 private_handle_t *hnd = (private_handle_t *)layer->handle;
2263 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002264 if (!(layer->flags & HWC_COLOR_FILL)) {
2265 ALOGE("%s handle null", __FUNCTION__);
2266 return false;
2267 }
2268 // No PLAY for Color layer
2269 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2270 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002271 }
2272
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002273 int mdpIndex = mCurrentFrame.layerToMDP[i];
2274
Raj Kamal389d6e32014-08-04 14:43:24 +05302275 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302276 {
2277 MdpYUVPipeInfo& pipe_info =
2278 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2279 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2280 ovutils::eDest indexL = pipe_info.lIndex;
2281 ovutils::eDest indexR = pipe_info.rIndex;
2282 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302283 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302284 if(rot) {
2285 rot->queueBuffer(fd, offset);
2286 fd = rot->getDstMemId();
2287 offset = rot->getDstOffset();
2288 }
2289 if(indexL != ovutils::OV_INVALID) {
2290 ovutils::eDest destL = (ovutils::eDest)indexL;
2291 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2292 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2293 if (!ov.queueBuffer(fd, offset, destL)) {
2294 ALOGE("%s: queueBuffer failed for display:%d",
2295 __FUNCTION__, mDpy);
2296 return false;
2297 }
2298 }
2299
2300 if(indexR != ovutils::OV_INVALID) {
2301 ovutils::eDest destR = (ovutils::eDest)indexR;
2302 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2303 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2304 if (!ov.queueBuffer(fd, offset, destR)) {
2305 ALOGE("%s: queueBuffer failed for display:%d",
2306 __FUNCTION__, mDpy);
2307 return false;
2308 }
2309 }
2310 }
2311 else{
2312 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002313 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302314 ovutils::eDest dest = pipe_info.index;
2315 if(dest == ovutils::OV_INVALID) {
2316 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002317 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302318 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002319
radhakrishnac9a67412013-09-25 17:40:42 +05302320 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2321 continue;
2322 }
2323
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002324 int fd = hnd->fd;
2325 uint32_t offset = (uint32_t)hnd->offset;
2326 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2327 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002328 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002329 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002330 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002331 }
2332
radhakrishnac9a67412013-09-25 17:40:42 +05302333 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2334 using pipe: %d", __FUNCTION__, layer,
2335 hnd, dest );
2336
radhakrishnac9a67412013-09-25 17:40:42 +05302337 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2338 if(rot) {
2339 if(!rot->queueBuffer(fd, offset))
2340 return false;
2341 fd = rot->getDstMemId();
2342 offset = rot->getDstOffset();
2343 }
2344
2345 if (!ov.queueBuffer(fd, offset, dest)) {
2346 ALOGE("%s: queueBuffer failed for display:%d ",
2347 __FUNCTION__, mDpy);
2348 return false;
2349 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002350 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002351
2352 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002353 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002354 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002355}
2356
Saurabh Shah88e4d272013-09-03 13:31:29 -07002357//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002358
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002359void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302360 hwc_display_contents_1_t* list){
2361 //if 4kx2k yuv layer is totally present in either in left half
2362 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302363 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302364 if(mCurrentFrame.fbZ >= 0) {
2365 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2366 index++) {
2367 if(!mCurrentFrame.isFBComposed[index]) {
2368 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2369 mdpNextZOrder++;
2370 }
2371 mdpNextZOrder++;
2372 hwc_layer_1_t* layer = &list->hwLayers[index];
2373 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002374 if(isYUVSplitNeeded(hnd) ||
2375 (needs3DComposition(ctx,mDpy) &&
2376 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302377 hwc_rect_t dst = layer->displayFrame;
2378 if((dst.left > lSplit) || (dst.right < lSplit)) {
2379 mCurrentFrame.mdpCount += 1;
2380 }
2381 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2382 mCurrentFrame.fbZ += 1;
2383 mdpNextZOrder++;
2384 }
2385 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002386 }
radhakrishnac9a67412013-09-25 17:40:42 +05302387 }
2388}
2389
Saurabh Shah88e4d272013-09-03 13:31:29 -07002390bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002391 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002392
Saurabh Shahc62f3982014-03-05 14:28:26 -08002393 const int lSplit = getLeftSplit(ctx, mDpy);
2394 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002395 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002396 pipe_info.lIndex = ovutils::OV_INVALID;
2397 pipe_info.rIndex = ovutils::OV_INVALID;
2398
Saurabh Shahc62f3982014-03-05 14:28:26 -08002399 Overlay::PipeSpecs pipeSpecs;
2400 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2401 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2402 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2403 pipeSpecs.dpy = mDpy;
2404 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2405 pipeSpecs.fb = false;
2406
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002407 // Acquire pipe only for the updating half
2408 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2409 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2410
2411 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002412 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002413 if(pipe_info.lIndex == ovutils::OV_INVALID)
2414 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002415 }
2416
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002417 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002418 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2419 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002420 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002421 return false;
2422 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002423
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002424 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002425}
2426
Saurabh Shah88e4d272013-09-03 13:31:29 -07002427bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002428 hwc_display_contents_1_t* list) {
2429 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002430
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002431 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002432
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002433 hwc_layer_1_t* layer = &list->hwLayers[index];
2434 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302435 hwc_rect_t dst = layer->displayFrame;
2436 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302437 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302438 if((dst.left > lSplit)||(dst.right < lSplit)){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002439 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302440 continue;
2441 }
2442 }
2443 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002444 //XXX: Check for forced 2D composition
2445 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2446 if(allocSplitVGPipes(ctx,index))
2447 continue;
2448
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002449 int mdpIndex = mCurrentFrame.layerToMDP[index];
2450 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002451 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002452 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002453 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002454
Saurabh Shahc62f3982014-03-05 14:28:26 -08002455 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2456 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2457 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002458 return false;
2459 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002460 }
2461 return true;
2462}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002463
radhakrishnac9a67412013-09-25 17:40:42 +05302464int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2465 PipeLayerPair& PipeLayerPair) {
2466 const int lSplit = getLeftSplit(ctx, mDpy);
2467 hwc_rect_t dst = layer->displayFrame;
2468 if((dst.left > lSplit)||(dst.right < lSplit)){
2469 MdpYUVPipeInfo& mdp_info =
2470 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2471 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302472 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302473 eDest lDest = mdp_info.lIndex;
2474 eDest rDest = mdp_info.rIndex;
2475
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002476 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302477 lDest, rDest, &PipeLayerPair.rot);
2478 }
2479 else{
2480 return configure(ctx, layer, PipeLayerPair);
2481 }
2482}
2483
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002484/*
2485 * Configures pipe(s) for MDP composition
2486 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002487int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002488 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002489 MdpPipeInfoSplit& mdp_info =
2490 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002491 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302492 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002493 eDest lDest = mdp_info.lIndex;
2494 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002495
2496 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002497 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002498
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002499 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002500 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002501}
2502
Saurabh Shah88e4d272013-09-03 13:31:29 -07002503bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002504
Raj Kamal4393eaa2014-06-06 13:45:20 +05302505 if(!isEnabled() or !mModeOn) {
2506 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302507 return true;
2508 }
2509
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002510 // Set the Handle timeout to true for MDP or MIXED composition.
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002511 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount &&
2512 !(needs3DComposition(ctx, HWC_DISPLAY_PRIMARY) ||
2513 needs3DComposition(ctx, HWC_DISPLAY_EXTERNAL))) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002514 sHandleTimeout = true;
2515 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002516
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002517 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002518 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002519
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002520 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2521 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002522 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002523 if(mCurrentFrame.isFBComposed[i]) continue;
2524
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002525 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002526 private_handle_t *hnd = (private_handle_t *)layer->handle;
2527 if(!hnd) {
2528 ALOGE("%s handle null", __FUNCTION__);
2529 return false;
2530 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002531
2532 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2533 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002534 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002535
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002536 int mdpIndex = mCurrentFrame.layerToMDP[i];
2537
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002538 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2539 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302540 {
2541 MdpYUVPipeInfo& pipe_info =
2542 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2543 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2544 ovutils::eDest indexL = pipe_info.lIndex;
2545 ovutils::eDest indexR = pipe_info.rIndex;
2546 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302547 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302548 if(rot) {
2549 rot->queueBuffer(fd, offset);
2550 fd = rot->getDstMemId();
2551 offset = rot->getDstOffset();
2552 }
2553 if(indexL != ovutils::OV_INVALID) {
2554 ovutils::eDest destL = (ovutils::eDest)indexL;
2555 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2556 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2557 if (!ov.queueBuffer(fd, offset, destL)) {
2558 ALOGE("%s: queueBuffer failed for display:%d",
2559 __FUNCTION__, mDpy);
2560 return false;
2561 }
2562 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002563
radhakrishnac9a67412013-09-25 17:40:42 +05302564 if(indexR != ovutils::OV_INVALID) {
2565 ovutils::eDest destR = (ovutils::eDest)indexR;
2566 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2567 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2568 if (!ov.queueBuffer(fd, offset, destR)) {
2569 ALOGE("%s: queueBuffer failed for display:%d",
2570 __FUNCTION__, mDpy);
2571 return false;
2572 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002573 }
2574 }
radhakrishnac9a67412013-09-25 17:40:42 +05302575 else{
2576 MdpPipeInfoSplit& pipe_info =
2577 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2578 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002579
radhakrishnac9a67412013-09-25 17:40:42 +05302580 ovutils::eDest indexL = pipe_info.lIndex;
2581 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002582
radhakrishnac9a67412013-09-25 17:40:42 +05302583 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002584 uint32_t offset = (uint32_t)hnd->offset;
2585 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2586 if (!mDpy && (index != -1)) {
2587 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2588 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002589 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002590 }
radhakrishnac9a67412013-09-25 17:40:42 +05302591
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002592 if(ctx->mAD->draw(ctx, fd, offset)) {
2593 fd = ctx->mAD->getDstFd();
2594 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002595 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002596
radhakrishnac9a67412013-09-25 17:40:42 +05302597 if(rot) {
2598 rot->queueBuffer(fd, offset);
2599 fd = rot->getDstMemId();
2600 offset = rot->getDstOffset();
2601 }
2602
2603 //************* play left mixer **********
2604 if(indexL != ovutils::OV_INVALID) {
2605 ovutils::eDest destL = (ovutils::eDest)indexL;
2606 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2607 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2608 if (!ov.queueBuffer(fd, offset, destL)) {
2609 ALOGE("%s: queueBuffer failed for left mixer",
2610 __FUNCTION__);
2611 return false;
2612 }
2613 }
2614
2615 //************* play right mixer **********
2616 if(indexR != ovutils::OV_INVALID) {
2617 ovutils::eDest destR = (ovutils::eDest)indexR;
2618 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2619 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2620 if (!ov.queueBuffer(fd, offset, destR)) {
2621 ALOGE("%s: queueBuffer failed for right mixer",
2622 __FUNCTION__);
2623 return false;
2624 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002625 }
2626 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002627
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002628 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2629 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002630
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002631 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002632}
Saurabh Shahab47c692014-02-12 18:45:57 -08002633
2634//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002635
2636bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2637 hwc_display_contents_1_t* list) {
2638 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2639 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2640
2641 for(int i = numAppLayers - 1; i >= 0; i--) {
2642 if(!isValidRect(visibleRect)) {
2643 mCurrentFrame.drop[i] = true;
2644 mCurrentFrame.dropCount++;
2645 continue;
2646 }
2647
2648 const hwc_layer_1_t* layer = &list->hwLayers[i];
2649 hwc_rect_t dstRect = layer->displayFrame;
2650 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2651
2652 if(!isValidRect(res)) {
2653 mCurrentFrame.drop[i] = true;
2654 mCurrentFrame.dropCount++;
2655 } else {
2656 /* Reset frame ROI when any layer which needs scaling also needs ROI
2657 * cropping */
2658 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2659 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2660 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2661 mCurrentFrame.dropCount = 0;
2662 return false;
2663 }
2664
2665 /* deduct any opaque region from visibleRect */
2666 if (layer->blending == HWC_BLENDING_NONE &&
2667 layer->planeAlpha == 0xFF)
2668 visibleRect = deductRect(visibleRect, res);
2669 }
2670 }
2671 return true;
2672}
2673
2674/*
2675 * HW Limitation: ping pong split can always split the ping pong output
2676 * equally across two DSI's. So the ROI programmed should be of equal width
2677 * for both the halves
2678 */
2679void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2680 hwc_display_contents_1_t* list) {
2681 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2682
2683
2684 if(!canPartialUpdate(ctx, list))
2685 return;
2686
2687 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2688 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2689 (int)ctx->dpyAttr[mDpy].yres};
2690
2691 for(int index = 0; index < numAppLayers; index++ ) {
2692 hwc_layer_1_t* layer = &list->hwLayers[index];
2693
2694 // If we have a RGB layer which needs rotation, no partial update
2695 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2696 return;
2697
2698 if ((mCachedFrame.hnd[index] != layer->handle) ||
2699 isYuvBuffer((private_handle_t *)layer->handle)) {
2700 hwc_rect_t dst = layer->displayFrame;
2701 hwc_rect_t updatingRect = dst;
2702
2703#ifdef QCOM_BSP
2704 if(!needsScaling(layer) && !layer->transform)
2705 {
2706 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2707 int x_off = dst.left - src.left;
2708 int y_off = dst.top - src.top;
2709 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2710 }
2711#endif
2712
2713 roi = getUnion(roi, updatingRect);
2714 }
2715 }
2716
2717 /* No layer is updating. Still SF wants a refresh.*/
2718 if(!isValidRect(roi))
2719 return;
2720
2721 roi = expandROIFromMidPoint(roi, fullFrame);
2722
2723 hwc_rect lFrame = fullFrame;
2724 lFrame.right /= 2;
2725 hwc_rect lRoi = getIntersection(roi, lFrame);
2726
2727 // Align ROI coordinates to panel restrictions
2728 lRoi = getSanitizeROI(lRoi, lFrame);
2729
2730 hwc_rect rFrame = fullFrame;
2731 rFrame.left = lFrame.right;
2732 hwc_rect rRoi = getIntersection(roi, rFrame);
2733
2734 // Align ROI coordinates to panel restrictions
2735 rRoi = getSanitizeROI(rRoi, rFrame);
2736
2737 roi = getUnion(lRoi, rRoi);
2738
2739 ctx->listStats[mDpy].lRoi = roi;
2740 if(!validateAndApplyROI(ctx, list))
2741 resetROI(ctx, mDpy);
2742
2743 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2744 __FUNCTION__,
2745 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2746 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2747 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2748 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2749}
2750
Saurabh Shahab47c692014-02-12 18:45:57 -08002751bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002752 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002753 private_handle_t *hnd = (private_handle_t *)layer->handle;
2754 hwc_rect_t dst = layer->displayFrame;
2755 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2756 pipe_info.lIndex = ovutils::OV_INVALID;
2757 pipe_info.rIndex = ovutils::OV_INVALID;
2758
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002759 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2760 trimAgainstROI(ctx,crop, dst);
2761
Saurabh Shahab47c692014-02-12 18:45:57 -08002762 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2763 //should have a higher priority than the right one. Pipe priorities are
2764 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002765
Saurabh Shahc62f3982014-03-05 14:28:26 -08002766 Overlay::PipeSpecs pipeSpecs;
2767 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2768 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2769 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2770 pipeSpecs.dpy = mDpy;
2771 pipeSpecs.fb = false;
2772
Saurabh Shahab47c692014-02-12 18:45:57 -08002773 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002774 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002775 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002776 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002777 }
2778
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002779 /* Use 2 pipes IF
2780 a) Layer's crop width is > 2048 or
2781 b) Layer's dest width > 2048 or
2782 c) On primary, driver has indicated with caps to split always. This is
2783 based on an empirically derived value of panel height. Applied only
2784 if the layer's width is > mixer's width
2785 */
2786
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302787 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002788 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302789 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002790 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2791 const uint32_t dstWidth = dst.right - dst.left;
2792 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002793 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002794 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002795 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002796 crop.bottom - crop.top;
2797 //Approximation to actual clock, ignoring the common factors in pipe and
2798 //mixer cases like line_time
2799 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2800 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002801
Saurabh Shah05f4e222015-02-05 14:36:22 -08002802 const uint32_t downscale = getRotDownscale(ctx, layer);
2803 if(downscale) {
2804 cropWidth /= downscale;
2805 cropHeight /= downscale;
2806 }
2807
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002808 if(dstWidth > mdpHw.getMaxPipeWidth() or
2809 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002810 (primarySplitAlways and
2811 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002812 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002813 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002814 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002815 }
2816
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002817 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2818 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002819 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002820 }
2821 }
2822
2823 return true;
2824}
2825
Saurabh Shahab47c692014-02-12 18:45:57 -08002826int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2827 PipeLayerPair& PipeLayerPair) {
2828 private_handle_t *hnd = (private_handle_t *)layer->handle;
2829 if(!hnd) {
2830 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2831 return -1;
2832 }
2833 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2834 MdpPipeInfoSplit& mdp_info =
2835 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2836 Rotator **rot = &PipeLayerPair.rot;
2837 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002838 eDest lDest = mdp_info.lIndex;
2839 eDest rDest = mdp_info.rIndex;
2840 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2841 hwc_rect_t dst = layer->displayFrame;
2842 int transform = layer->transform;
2843 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002844 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002845 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002846 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002847 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08002848
2849 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2850 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2851
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002852 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2853 /* MDP driver crops layer coordinates against ROI in Non-Split
2854 * and Split MDP comp. But HWC needs to crop them for source split.
2855 * Reason: 1) Source split is efficient only when the final effective
2856 * load is distributed evenly across mixers.
2857 * 2) We have to know the effective width of the layer that
2858 * the ROI needs to find the no. of pipes the layer needs.
2859 */
2860 trimAgainstROI(ctx, crop, dst);
2861 }
2862
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002863 if(needs3DComposition(ctx, mDpy) &&
2864 get3DFormat(hnd) != HAL_NO_3D){
2865 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
2866 rDest, &PipeLayerPair.rot);
2867 }
2868
Saurabh Shahab47c692014-02-12 18:45:57 -08002869 // Handle R/B swap
2870 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2871 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2872 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2873 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2874 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2875 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002876 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002877 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2878 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002879 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002880 /* Calculate the external display position based on MDP downscale,
2881 ActionSafe, and extorientation features. */
2882 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002883
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002884 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002885 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002886
2887 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2888 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002889 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002890 }
2891
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002892 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002893 (*rot) = ctx->mRotMgr->getNext();
2894 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002895 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002896 //If the video is using a single pipe, enable BWC
2897 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002898 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2899 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002900 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002901 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002902 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002903 ALOGE("%s: configRotator failed!", __FUNCTION__);
2904 return -1;
2905 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002906 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002907 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002908 }
2909
2910 //If 2 pipes being used, divide layer into half, crop and dst
2911 hwc_rect_t cropL = crop;
2912 hwc_rect_t cropR = crop;
2913 hwc_rect_t dstL = dst;
2914 hwc_rect_t dstR = dst;
2915 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2916 cropL.right = (crop.right + crop.left) / 2;
2917 cropR.left = cropL.right;
2918 sanitizeSourceCrop(cropL, cropR, hnd);
2919
Saurabh Shahb729b192014-08-15 18:04:24 -07002920 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002921 //Swap crops on H flip since 2 pipes are being used
2922 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2923 hwc_rect_t tmp = cropL;
2924 cropL = cropR;
2925 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002926 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002927 }
2928
Saurabh Shahb729b192014-08-15 18:04:24 -07002929 //cropSwap trick: If the src and dst widths are both odd, let us say
2930 //2507, then splitting both into half would cause left width to be 1253
2931 //and right 1254. If crop is swapped because of H flip, this will cause
2932 //left crop width to be 1254, whereas left dst width remains 1253, thus
2933 //inducing a scaling that is unaccounted for. To overcome that we add 1
2934 //to the dst width if there is a cropSwap. So if the original width was
2935 //2507, the left dst width will be 1254. Even if the original width was
2936 //even for ex: 2508, the left dst width will still remain 1254.
2937 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002938 dstR.left = dstL.right;
2939 }
2940
2941 //For the mdp, since either we are pre-rotating or MDP does flips
2942 orient = OVERLAY_TRANSFORM_0;
2943 transform = 0;
2944
2945 //configure left pipe
2946 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002947 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002948 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2949 (ovutils::eBlending) getBlending(layer->blending));
2950
2951 if(configMdp(ctx->mOverlay, pargL, orient,
2952 cropL, dstL, metadata, lDest) < 0) {
2953 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2954 return -1;
2955 }
2956 }
2957
2958 //configure right pipe
2959 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002960 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002961 static_cast<eRotFlags>(rotFlags),
2962 layer->planeAlpha,
2963 (ovutils::eBlending) getBlending(layer->blending));
2964 if(configMdp(ctx->mOverlay, pargR, orient,
2965 cropR, dstR, metadata, rDest) < 0) {
2966 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2967 return -1;
2968 }
2969 }
2970
2971 return 0;
2972}
2973
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002974bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2975 Locker::Autolock _l(ctx->mDrawLock);
2976 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2977 char path[MAX_SYSFS_FILE_PATH];
2978 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2979 int fd = open(path, O_RDONLY);
2980 if(fd < 0) {
2981 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2982 return -1;
2983 }
2984 char value[4];
2985 ssize_t size_read = read(fd, value, sizeof(value)-1);
2986 if(size_read <= 0) {
2987 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2988 close(fd);
2989 return -1;
2990 }
2991 close(fd);
2992 value[size_read] = '\0';
2993 return atoi(value);
2994}
2995
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002996int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2997 Locker::Autolock _l(ctx->mDrawLock);
2998 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2999 char path[MAX_SYSFS_FILE_PATH];
3000 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3001 int fd = open(path, O_WRONLY);
3002 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003003 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003004 return -1;
3005 }
3006 char value[4];
3007 snprintf(value, sizeof(value), "%d", (int)enable);
3008 ssize_t ret = write(fd, value, strlen(value));
3009 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003010 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003011 close(fd);
3012 return -1;
3013 }
3014 close(fd);
3015 sIsPartialUpdateActive = enable;
3016 return 0;
3017}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003018
3019bool MDPComp::loadPerfLib() {
3020 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3021 bool success = false;
3022 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3023 ALOGE("vendor library not set in ro.vendor.extension_library");
3024 return false;
3025 }
3026
3027 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3028 if(sLibPerfHint) {
3029 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3030 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3031 if (!sPerfLockAcquire || !sPerfLockRelease) {
3032 ALOGE("Failed to load symbols for perfLock");
3033 dlclose(sLibPerfHint);
3034 sLibPerfHint = NULL;
3035 return false;
3036 }
3037 success = true;
3038 ALOGI("Successfully Loaded perf hint API's");
3039 } else {
3040 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3041 }
3042 return success;
3043}
3044
3045void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3046 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3047 return;
3048 }
3049 static int count = sPerfHintWindow;
3050 static int perflockFlag = 0;
3051
3052 /* Send hint to mpctl when single layer is updated
3053 * for a successful number of windows. Hint release
3054 * happens immediately upon multiple layer update.
3055 */
3056 if (onlyVideosUpdating(ctx, list)) {
3057 if(count) {
3058 count--;
3059 }
3060 } else {
3061 if (perflockFlag) {
3062 perflockFlag = 0;
3063 sPerfLockRelease(sPerfLockHandle);
3064 }
3065 count = sPerfHintWindow;
3066 }
3067 if (count == 0 && !perflockFlag) {
3068 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3069 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3070 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003071 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003072 perflockFlag = 1;
3073 }
3074 }
3075}
3076
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003077}; //namespace
3078