blob: caa1344e3fefb4ce6a1c851f478ca9fd792d73fc [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();
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530220 resetROI(ctx, mDpy);
221 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
222 mCurrentFrame.dropCount = 0;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700223}
224
Raj Kamal4393eaa2014-06-06 13:45:20 +0530225void MDPComp::reset() {
226 sHandleTimeout = false;
227 mModeOn = false;
228}
229
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700230void MDPComp::timeout_handler(void *udata) {
231 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
232
233 if(!ctx) {
234 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
235 return;
236 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530237
238 ctx->mDrawLock.lock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800239 // Handle timeout event only if the previous composition is MDP or MIXED.
240 if(!sHandleTimeout) {
241 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530242 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800243 return;
244 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700245 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700246 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530247 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700248 return;
249 }
250 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530251 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700252 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700253 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700254}
255
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700256void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
257 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800258 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700259 if(value > maxSupported) {
260 ALOGW("%s: Input exceeds max value supported. Setting to"
261 "max value: %d", __FUNCTION__, maxSupported);
262 }
263 sMaxPipesPerMixer = min(value, maxSupported);
264}
265
Saurabh Shah59562ff2014-09-30 16:13:12 -0700266void MDPComp::setIdleTimeout(const uint32_t& timeout) {
267 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
268
269 if(sIdleInvalidator) {
270 if(timeout <= ONE_REFRESH_PERIOD_MS) {
271 //If the specified timeout is < 1 draw cycle worth, "virtually"
272 //disable idle timeout. The ideal way for clients to disable
273 //timeout is to set it to 0
274 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
275 ALOGI("Disabled idle timeout");
276 return;
277 }
278 sIdleInvalidator->setIdleTimeout(timeout);
279 ALOGI("Idle timeout set to %u", timeout);
280 } else {
281 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
282 }
283}
284
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800285void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 hwc_display_contents_1_t* list) {
287 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800288
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800289 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800290 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800291 if(!mCurrentFrame.isFBComposed[index]) {
292 layerProp[index].mFlags |= HWC_MDPCOMP;
293 layer->compositionType = HWC_OVERLAY;
294 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800295 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700296 /* Drop the layer when its already present in FB OR when it lies
297 * outside frame's ROI */
298 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800299 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700300 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800301 }
302 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700303}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500304
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800305void MDPComp::setRedraw(hwc_context_t *ctx,
306 hwc_display_contents_1_t* list) {
307 mCurrentFrame.needsRedraw = false;
308 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
309 (list->flags & HWC_GEOMETRY_CHANGED) ||
310 isSkipPresent(ctx, mDpy)) {
311 mCurrentFrame.needsRedraw = true;
312 }
313}
314
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700316 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700317 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800318}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800319
Saurabh Shahaa236822013-04-24 18:07:26 -0700320void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700321 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800322 if(mdpToLayer[i].pipeInfo) {
323 delete mdpToLayer[i].pipeInfo;
324 mdpToLayer[i].pipeInfo = NULL;
325 //We dont own the rotator
326 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800327 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800328 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800329
330 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
331 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700332 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800333
Saurabh Shahaa236822013-04-24 18:07:26 -0700334 layerCount = numLayers;
335 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700337 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800338 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800339}
340
Saurabh Shahaa236822013-04-24 18:07:26 -0700341void MDPComp::FrameInfo::map() {
342 // populate layer and MDP maps
343 int mdpIdx = 0;
344 for(int idx = 0; idx < layerCount; idx++) {
345 if(!isFBComposed[idx]) {
346 mdpToLayer[mdpIdx].listIndex = idx;
347 layerToMDP[idx] = mdpIdx++;
348 }
349 }
350}
351
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800352MDPComp::LayerCache::LayerCache() {
353 reset();
354}
355
356void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700357 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530358 memset(&isFBComposed, true, sizeof(isFBComposed));
359 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800360 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700361}
362
363void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530364 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700365 for(int i = 0; i < numAppLayers; i++) {
366 hnd[i] = list->hwLayers[i].handle;
367 }
368}
369
370void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700371 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530372 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
373 memcpy(&drop, &curFrame.drop, sizeof(drop));
374}
375
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800376bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
377 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530378 if(layerCount != curFrame.layerCount)
379 return false;
380 for(int i = 0; i < curFrame.layerCount; i++) {
381 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
382 (curFrame.drop[i] != drop[i])) {
383 return false;
384 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800385 if(curFrame.isFBComposed[i] &&
386 (hnd[i] != list->hwLayers[i].handle)){
387 return false;
388 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530389 }
390 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800391}
392
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700393bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
394 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800395 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530396 (not isValidDimension(ctx,layer)) ||
397 isSkipLayer(layer)) {
398 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700399 return false;
400 }
401 return true;
402}
403
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530404bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800405 private_handle_t *hnd = (private_handle_t *)layer->handle;
406
407 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700408 if (layer->flags & HWC_COLOR_FILL) {
409 // Color layer
410 return true;
411 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700412 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800413 return false;
414 }
415
Naseer Ahmede850a802013-09-06 13:12:52 -0400416 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400417 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400418 return false;
419
Saurabh Shah62e1d732013-09-17 10:44:05 -0700420 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700421 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700422 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700423 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
424 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700425 int dst_w = dst.right - dst.left;
426 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800427 float w_scale = ((float)crop_w / (float)dst_w);
428 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530429 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700430
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800431 /* Workaround for MDP HW limitation in DSI command mode panels where
432 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
433 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530434 * There also is a HW limilation in MDP, minimum block size is 2x2
435 * Fallback to GPU if height is less than 2.
436 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700437 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800438 return false;
439
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800440 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530441 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800442 const float w_dscale = w_scale;
443 const float h_dscale = h_scale;
444
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800445 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700446
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530447 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700448 /* On targets that doesnt support Decimation (eg.,8x26)
449 * maximum downscale support is overlay pipe downscale.
450 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800451 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530452 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700453 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800454 return false;
455 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700456 // Decimation on macrotile format layers is not supported.
457 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530458 /* Bail out if
459 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700460 * 2. exceeds maximum downscale limit
461 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800462 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530463 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700464 w_dscale > maxMDPDownscale ||
465 h_dscale > maxMDPDownscale) {
466 return false;
467 }
468 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800469 return false;
470 }
471 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700472 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700473 return false;
474 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700475 }
476
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800477 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530478 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800479 const float w_uscale = 1.0f / w_scale;
480 const float h_uscale = 1.0f / h_scale;
481
482 if(w_uscale > upscale || h_uscale > upscale)
483 return false;
484 }
485
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800486 return true;
487}
488
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800489bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700490 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800491
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800492 if(!isEnabled()) {
493 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700494 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530495 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530496 qdutils::MDPVersion::getInstance().is8x16() ||
497 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800498 ctx->mVideoTransFlag &&
499 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700500 //1 Padding round to shift pipes across mixers
501 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
502 __FUNCTION__);
503 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700504 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
505 /* TODO: freeing up all the resources only for the targets having total
506 number of pipes < 8. Need to analyze number of VIG pipes used
507 for primary in previous draw cycle and accordingly decide
508 whether to fall back to full GPU comp or video only comp
509 */
510 if(isSecondaryConfiguring(ctx)) {
511 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
512 __FUNCTION__);
513 ret = false;
514 } else if(ctx->isPaddingRound) {
515 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
516 __FUNCTION__,mDpy);
517 ret = false;
518 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800519 } else if (ctx->isDMAStateChanging) {
520 // Bail out if a padding round has been invoked in order to switch DMA
521 // state to block mode. We need this to cater for the case when a layer
522 // requires rotation in the current frame.
523 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
524 __FUNCTION__);
525 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700526 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800527
Saurabh Shahaa236822013-04-24 18:07:26 -0700528 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800529}
530
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800531void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
532 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800534 dst = getIntersection(dst, roi);
535 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800536}
537
538/* 1) Identify layers that are not visible or lying outside the updating ROI and
539 * drop them from composition.
540 * 2) If we have a scaling layer which needs cropping against generated
541 * ROI, reset ROI to full resolution. */
542bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
543 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700544 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800545 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800546
547 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800548 if(!isValidRect(visibleRect)) {
549 mCurrentFrame.drop[i] = true;
550 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800551 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800552 }
553
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700554 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700555 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800556 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700557
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700558 if(!isValidRect(res)) {
559 mCurrentFrame.drop[i] = true;
560 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800561 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700562 /* Reset frame ROI when any layer which needs scaling also needs ROI
563 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800564 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800565 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700566 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
567 mCurrentFrame.dropCount = 0;
568 return false;
569 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800570
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800571 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530572 if (layer->blending == HWC_BLENDING_NONE &&
573 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800574 visibleRect = deductRect(visibleRect, res);
575 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700576 }
577 return true;
578}
579
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800580/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
581 * are updating. If DirtyRegion is applicable, calculate it by accounting all
582 * the changing layer's dirtyRegion. */
583void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
584 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700585 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800586 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700587 return;
588
589 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800590 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
591 (int)ctx->dpyAttr[mDpy].yres};
592
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700593 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800594 hwc_layer_1_t* layer = &list->hwLayers[index];
595 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800596 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700597 hwc_rect_t dst = layer->displayFrame;
598 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800599
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800600#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530601 if(!needsScaling(layer) && !layer->transform &&
602 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700603 {
604 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
605 int x_off = dst.left - src.left;
606 int y_off = dst.top - src.top;
607 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
608 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800609#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800610
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800611 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700612 }
613 }
614
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800615 /* No layer is updating. Still SF wants a refresh.*/
616 if(!isValidRect(roi))
617 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800618
619 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800620 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800621
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800622 ctx->listStats[mDpy].lRoi = roi;
623 if(!validateAndApplyROI(ctx, list))
624 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700625
626 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800627 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
628 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
629}
630
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800631void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
632 hwc_rect &dst) {
633 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
634 ctx->listStats[mDpy].rRoi);
635 hwc_rect tmpDst = getIntersection(dst, roi);
636 if(!isSameRect(dst, tmpDst)) {
637 crop.left = crop.left + (tmpDst.left - dst.left);
638 crop.top = crop.top + (tmpDst.top - dst.top);
639 crop.right = crop.left + (tmpDst.right - tmpDst.left);
640 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
641 dst = tmpDst;
642 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800643}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800644
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800645/* 1) Identify layers that are not visible or lying outside BOTH the updating
646 * ROI's and drop them from composition. If a layer is spanning across both
647 * the halves of the screen but needed by only ROI, the non-contributing
648 * half will not be programmed for MDP.
649 * 2) If we have a scaling layer which needs cropping against generated
650 * ROI, reset ROI to full resolution. */
651bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
652 hwc_display_contents_1_t* list) {
653
654 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
655
656 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
657 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
658
659 for(int i = numAppLayers - 1; i >= 0; i--){
660 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
661 {
662 mCurrentFrame.drop[i] = true;
663 mCurrentFrame.dropCount++;
664 continue;
665 }
666
667 const hwc_layer_1_t* layer = &list->hwLayers[i];
668 hwc_rect_t dstRect = layer->displayFrame;
669
670 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
671 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
672 hwc_rect_t res = getUnion(l_res, r_res);
673
674 if(!isValidRect(l_res) && !isValidRect(r_res)) {
675 mCurrentFrame.drop[i] = true;
676 mCurrentFrame.dropCount++;
677 } else {
678 /* Reset frame ROI when any layer which needs scaling also needs ROI
679 * cropping */
680 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
681 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
682 mCurrentFrame.dropCount = 0;
683 return false;
684 }
685
radhakrishna4efbdd62014-11-03 13:19:27 +0530686 if (layer->blending == HWC_BLENDING_NONE &&
687 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800688 visibleRectL = deductRect(visibleRectL, l_res);
689 visibleRectR = deductRect(visibleRectR, r_res);
690 }
691 }
692 }
693 return true;
694}
695/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
696 * are updating. If DirtyRegion is applicable, calculate it by accounting all
697 * the changing layer's dirtyRegion. */
698void MDPCompSplit::generateROI(hwc_context_t *ctx,
699 hwc_display_contents_1_t* list) {
700 if(!canPartialUpdate(ctx, list))
701 return;
702
703 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
704 int lSplit = getLeftSplit(ctx, mDpy);
705
706 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
707 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
708
709 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
710 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
711
712 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
713 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
714
715 for(int index = 0; index < numAppLayers; index++ ) {
716 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800717 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800718 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800719 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700720 hwc_rect_t dst = layer->displayFrame;
721 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800722
723#ifdef QCOM_BSP
724 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700725 {
726 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
727 int x_off = dst.left - src.left;
728 int y_off = dst.top - src.top;
729 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
730 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800731#endif
732
733 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
734 if(isValidRect(l_dst))
735 l_roi = getUnion(l_roi, l_dst);
736
737 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
738 if(isValidRect(r_dst))
739 r_roi = getUnion(r_roi, r_dst);
740 }
741 }
742
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700743 /* For panels that cannot accept commands in both the interfaces, we cannot
744 * send two ROI's (for each half). We merge them into single ROI and split
745 * them across lSplit for MDP mixer use. The ROI's will be merged again
746 * finally before udpating the panel in the driver. */
747 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
748 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
749 l_roi = getIntersection(temp_roi, l_frame);
750 r_roi = getIntersection(temp_roi, r_frame);
751 }
752
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800753 /* No layer is updating. Still SF wants a refresh. */
754 if(!isValidRect(l_roi) && !isValidRect(r_roi))
755 return;
756
757 l_roi = getSanitizeROI(l_roi, l_frame);
758 r_roi = getSanitizeROI(r_roi, r_frame);
759
760 ctx->listStats[mDpy].lRoi = l_roi;
761 ctx->listStats[mDpy].rRoi = r_roi;
762
763 if(!validateAndApplyROI(ctx, list))
764 resetROI(ctx, mDpy);
765
766 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
767 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
768 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
769 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
770 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
771 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700772}
773
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800774/* Checks for conditions where all the layers marked for MDP comp cannot be
775 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800776bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800777 hwc_display_contents_1_t* list){
778
Saurabh Shahaa236822013-04-24 18:07:26 -0700779 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800780
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700781 // Fall back to video only composition, if AIV video mode is enabled
782 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700783 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
784 __FUNCTION__, mDpy);
785 return false;
786 }
787
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530788 /* No Idle fall back if secure display or secure RGB layers are present
789 * or if there is only a single layer being composed */
790 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
791 !ctx->listStats[mDpy].secureRGBCount &&
792 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700793 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
794 return false;
795 }
796
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700797 // if secondary is configuring or Padding round, fall back to video only
798 // composition and release all assigned non VIG pipes from primary.
799 if(isSecondaryConfiguring(ctx)) {
800 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
801 __FUNCTION__);
802 return false;
803 } else if(ctx->isPaddingRound) {
804 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
805 __FUNCTION__,mDpy);
806 return false;
807 }
808
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700809 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800810 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700811 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800812 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
813 return false;
814 }
815
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800816 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800817 hwc_layer_1_t* layer = &list->hwLayers[i];
818 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800819
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800820 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700821 if(!canUseRotator(ctx, mDpy)) {
822 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
823 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700824 return false;
825 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800826 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530827
828 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
829 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800830 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700831 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530832 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
833 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
834 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800835 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700836
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700837 if(ctx->mAD->isDoable()) {
838 return false;
839 }
840
Saurabh Shahaa236822013-04-24 18:07:26 -0700841 //If all above hard conditions are met we can do full or partial MDP comp.
842 bool ret = false;
843 if(fullMDPComp(ctx, list)) {
844 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700845 } else if(fullMDPCompWithPTOR(ctx, list)) {
846 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700847 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700848 ret = true;
849 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530850
Saurabh Shahaa236822013-04-24 18:07:26 -0700851 return ret;
852}
853
854bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700855
856 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
857 return false;
858
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700859 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
860 for(int i = 0; i < numAppLayers; i++) {
861 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700862 if(not mCurrentFrame.drop[i] and
863 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700864 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
865 return false;
866 }
867 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800868
Saurabh Shahaa236822013-04-24 18:07:26 -0700869 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700870 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
871 sizeof(mCurrentFrame.isFBComposed));
872 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
873 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700874
Raj Kamal389d6e32014-08-04 14:43:24 +0530875 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800876 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530877 }
878
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800879 if(!postHeuristicsHandling(ctx, list)) {
880 ALOGD_IF(isDebug(), "post heuristic handling failed");
881 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700882 return false;
883 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700884 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
885 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700886 return true;
887}
888
Sushil Chauhandefd3522014-05-13 18:17:12 -0700889/* Full MDP Composition with Peripheral Tiny Overlap Removal.
890 * MDP bandwidth limitations can be avoided, if the overlap region
891 * covered by the smallest layer at a higher z-order, gets composed
892 * by Copybit on a render buffer, which can be queued to MDP.
893 */
894bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
895 hwc_display_contents_1_t* list) {
896
897 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
898 const int stagesForMDP = min(sMaxPipesPerMixer,
899 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
900
901 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700902 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
904 return false;
905 }
906
907 // Frame level checks
908 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
909 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
910 isSecurePresent(ctx, mDpy)) {
911 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
912 return false;
913 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700914 // MDP comp checks
915 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700916 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700917 if(not isSupportedForMDPComp(ctx, layer)) {
918 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
919 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700920 }
921 }
922
Sushil Chauhandefd3522014-05-13 18:17:12 -0700923 /* We cannot use this composition mode, if:
924 1. A below layer needs scaling.
925 2. Overlap is not peripheral to display.
926 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700927 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700928 */
929
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700930 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
931 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
932 memset(overlapRect, 0, sizeof(overlapRect));
933 int layerPixelCount, minPixelCount = 0;
934 int numPTORLayersFound = 0;
935 for (int i = numAppLayers-1; (i >= 0 &&
936 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700937 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700939 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700940 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
941 // PTOR layer should be peripheral and cannot have transform
942 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
943 has90Transform(layer)) {
944 continue;
945 }
946 if((3 * (layerPixelCount + minPixelCount)) >
947 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
948 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
949 continue;
950 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700951 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700952 for (int j = i-1; j >= 0; j--) {
953 // Check if the layers below this layer qualifies for PTOR comp
954 hwc_layer_1_t* layer = &list->hwLayers[j];
955 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700956 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700957 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700958 if (isValidRect(getIntersection(dispFrame, disFrame))) {
959 if (has90Transform(layer) || needsScaling(layer)) {
960 found = false;
961 break;
962 }
963 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700964 }
965 }
966 // Store the minLayer Index
967 if(found) {
968 minLayerIndex[numPTORLayersFound] = i;
969 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
970 minPixelCount += layerPixelCount;
971 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700972 }
973 }
974
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700975 // No overlap layers
976 if (!numPTORLayersFound)
977 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700978
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700979 // Store the displayFrame and the sourceCrops of the layers
980 hwc_rect_t displayFrame[numAppLayers];
981 hwc_rect_t sourceCrop[numAppLayers];
982 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700983 hwc_layer_1_t* layer = &list->hwLayers[i];
984 displayFrame[i] = layer->displayFrame;
985 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700986 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700987
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530988 /**
989 * It's possible that 2 PTOR layers might have overlapping.
990 * In such case, remove the intersection(again if peripheral)
991 * from the lower PTOR layer to avoid overlapping.
992 * If intersection is not on peripheral then compromise
993 * by reducing number of PTOR layers.
994 **/
995 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
996 if(isValidRect(commonRect)) {
997 overlapRect[1] = deductRect(overlapRect[1], commonRect);
998 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
999 }
1000
1001 ctx->mPtorInfo.count = numPTORLayersFound;
1002 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1003 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1004 }
1005
1006 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1007 // reset PTOR
1008 ctx->mPtorInfo.count = 0;
1009 if(isValidRect(commonRect)) {
1010 // If PTORs are intersecting restore displayframe of PTOR[1]
1011 // before returning, as we have modified it above.
1012 list->hwLayers[minLayerIndex[1]].displayFrame =
1013 displayFrame[minLayerIndex[1]];
1014 }
1015 return false;
1016 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001017 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1018 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1019
Xu Yangcda012c2014-07-30 21:57:21 +08001020 // Store the blending mode, planeAlpha, and transform of PTOR layers
1021 int32_t blending[numPTORLayersFound];
1022 uint8_t planeAlpha[numPTORLayersFound];
1023 uint32_t transform[numPTORLayersFound];
1024
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001025 for(int j = 0; j < numPTORLayersFound; j++) {
1026 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001027
1028 // Update src crop of PTOR layer
1029 hwc_layer_1_t* layer = &list->hwLayers[index];
1030 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1031 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1032 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1033 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1034
1035 // Store & update w, h, format of PTOR layer
1036 private_handle_t *hnd = (private_handle_t *)layer->handle;
1037 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1038 layerWhf[j] = whf;
1039 hnd->width = renderBuf->width;
1040 hnd->height = renderBuf->height;
1041 hnd->format = renderBuf->format;
1042
Xu Yangcda012c2014-07-30 21:57:21 +08001043 // Store & update blending mode, planeAlpha and transform of PTOR layer
1044 blending[j] = layer->blending;
1045 planeAlpha[j] = layer->planeAlpha;
1046 transform[j] = layer->transform;
1047 layer->blending = HWC_BLENDING_NONE;
1048 layer->planeAlpha = 0xFF;
1049 layer->transform = 0;
1050
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001051 // Remove overlap from crop & displayFrame of below layers
1052 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001053 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001054 if(!isValidRect(getIntersection(layer->displayFrame,
1055 overlapRect[j]))) {
1056 continue;
1057 }
1058 // Update layer attributes
1059 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1060 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301061 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001062 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1063 layer->transform);
1064 layer->sourceCropf.left = (float)srcCrop.left;
1065 layer->sourceCropf.top = (float)srcCrop.top;
1066 layer->sourceCropf.right = (float)srcCrop.right;
1067 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1068 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001069 }
1070
1071 mCurrentFrame.mdpCount = numAppLayers;
1072 mCurrentFrame.fbCount = 0;
1073 mCurrentFrame.fbZ = -1;
1074
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301075 for (int j = 0; j < numAppLayers; j++) {
1076 if(isValidRect(list->hwLayers[j].displayFrame)) {
1077 mCurrentFrame.isFBComposed[j] = false;
1078 } else {
1079 mCurrentFrame.mdpCount--;
1080 mCurrentFrame.drop[j] = true;
1081 }
1082 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001083
1084 bool result = postHeuristicsHandling(ctx, list);
1085
1086 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001087 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001088 hwc_layer_1_t* layer = &list->hwLayers[i];
1089 layer->displayFrame = displayFrame[i];
1090 layer->sourceCropf.left = (float)sourceCrop[i].left;
1091 layer->sourceCropf.top = (float)sourceCrop[i].top;
1092 layer->sourceCropf.right = (float)sourceCrop[i].right;
1093 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1094 }
1095
Xu Yangcda012c2014-07-30 21:57:21 +08001096 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001097 for (int i = 0; i < numPTORLayersFound; i++) {
1098 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001099 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001100 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1101 hnd->width = layerWhf[i].w;
1102 hnd->height = layerWhf[i].h;
1103 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001104 layer->blending = blending[i];
1105 layer->planeAlpha = planeAlpha[i];
1106 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001107 }
1108
Sushil Chauhandefd3522014-05-13 18:17:12 -07001109 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001110 // reset PTOR
1111 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001112 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001113 } else {
1114 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1115 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001116 }
1117
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001118 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1119 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001120 return result;
1121}
1122
Saurabh Shahaa236822013-04-24 18:07:26 -07001123bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1124{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001125 if(!sEnableMixedMode) {
1126 //Mixed mode is disabled. No need to even try caching.
1127 return false;
1128 }
1129
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001130 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301131 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1132 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001133 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001134 cacheBasedComp(ctx, list);
1135 } else {
1136 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001137 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001138 }
1139
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001140 return ret;
1141}
1142
1143bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1144 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001145 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1146 return false;
1147
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001148 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001149 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001150 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001151
1152 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1153 for(int i = 0; i < numAppLayers; i++) {
1154 if(!mCurrentFrame.isFBComposed[i]) {
1155 hwc_layer_1_t* layer = &list->hwLayers[i];
1156 if(not isSupportedForMDPComp(ctx, layer)) {
1157 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1158 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001159 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001160 return false;
1161 }
1162 }
1163 }
1164
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001165 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001166 /* mark secure RGB layers for MDP comp */
1167 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301168 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001169 if(!ret) {
1170 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001171 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001172 return false;
1173 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001174
1175 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001176
Raj Kamal389d6e32014-08-04 14:43:24 +05301177 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001178 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301179 }
1180
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001181 if(!postHeuristicsHandling(ctx, list)) {
1182 ALOGD_IF(isDebug(), "post heuristic handling failed");
1183 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001184 return false;
1185 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001186 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1187 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001188
Saurabh Shahaa236822013-04-24 18:07:26 -07001189 return true;
1190}
1191
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001192bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001193 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001194 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1195 return false;
1196
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001197 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001198 return false;
1199 }
1200
Saurabh Shahb772ae32013-11-18 15:40:02 -08001201 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001202 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1203 const int stagesForMDP = min(sMaxPipesPerMixer,
1204 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001205
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001206 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1207 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1208 int lastMDPSupportedIndex = numAppLayers;
1209 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001210
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001211 //Find the minimum MDP batch size
1212 for(int i = 0; i < numAppLayers;i++) {
1213 if(mCurrentFrame.drop[i]) {
1214 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001215 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001216 }
1217 hwc_layer_1_t* layer = &list->hwLayers[i];
1218 if(not isSupportedForMDPComp(ctx, layer)) {
1219 lastMDPSupportedIndex = i;
1220 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1221 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001222 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001223 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001224 }
1225
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001226 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1227 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1228 mCurrentFrame.dropCount);
1229
1230 //Start at a point where the fb batch should at least have 2 layers, for
1231 //this mode to be justified.
1232 while(fbBatchSize < 2) {
1233 ++fbBatchSize;
1234 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001235 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001236
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001237 //If there are no layers for MDP, this mode doesnt make sense.
1238 if(mdpBatchSize < 1) {
1239 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1240 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001241 return false;
1242 }
1243
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001244 mCurrentFrame.reset(numAppLayers);
1245
1246 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1247 while(mdpBatchSize > 0) {
1248 //Mark layers for MDP comp
1249 int mdpBatchLeft = mdpBatchSize;
1250 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1251 if(mCurrentFrame.drop[i]) {
1252 continue;
1253 }
1254 mCurrentFrame.isFBComposed[i] = false;
1255 --mdpBatchLeft;
1256 }
1257
1258 mCurrentFrame.fbZ = mdpBatchSize;
1259 mCurrentFrame.fbCount = fbBatchSize;
1260 mCurrentFrame.mdpCount = mdpBatchSize;
1261
1262 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1263 __FUNCTION__, mdpBatchSize, fbBatchSize,
1264 mCurrentFrame.dropCount);
1265
1266 if(postHeuristicsHandling(ctx, list)) {
1267 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001268 __FUNCTION__);
1269 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1270 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001271 return true;
1272 }
1273
1274 reset(ctx);
1275 --mdpBatchSize;
1276 ++fbBatchSize;
1277 }
1278
1279 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001280}
1281
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001282bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301283 if(mDpy or isSecurePresent(ctx, mDpy) or
1284 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001285 return false;
1286 }
1287 return true;
1288}
1289
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001290bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1291 hwc_display_contents_1_t* list){
1292 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1293 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001294 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001295 return false;
1296 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001297 if(ctx->listStats[mDpy].secureUI)
1298 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001299 return true;
1300}
1301
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001302bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1303 hwc_display_contents_1_t* list) {
1304 const bool secureOnly = true;
1305 return videoOnlyComp(ctx, list, not secureOnly) or
1306 videoOnlyComp(ctx, list, secureOnly);
1307}
1308
1309bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001310 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001311 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1312 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301313
Saurabh Shahaa236822013-04-24 18:07:26 -07001314 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301315 if(!isSecurePresent(ctx, mDpy)) {
1316 /* Bail out if we are processing only secured video layers
1317 * and we dont have any */
1318 if(secureOnly) {
1319 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1320 return false;
1321 }
1322 /* No Idle fall back for secure video layers and if there is only
1323 * single layer being composed. */
1324 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1325 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1326 return false;
1327 }
1328 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001329
Saurabh Shahaa236822013-04-24 18:07:26 -07001330 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001331 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001332 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001333 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001334
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001335 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1336 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001337 return false;
1338 }
1339
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001340 if(mCurrentFrame.fbCount)
1341 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001342
Raj Kamal389d6e32014-08-04 14:43:24 +05301343 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001344 adjustForSourceSplit(ctx, list);
1345 }
1346
1347 if(!postHeuristicsHandling(ctx, list)) {
1348 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301349 if(errno == ENOBUFS) {
1350 ALOGD_IF(isDebug(), "SMP Allocation failed");
1351 //On SMP allocation failure in video only comp add padding round
1352 ctx->isPaddingRound = true;
1353 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001354 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001355 return false;
1356 }
1357
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001358 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1359 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001360 return true;
1361}
1362
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001363/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1364bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1365 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001366 // Fall back to video only composition, if AIV video mode is enabled
1367 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001368 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1369 __FUNCTION__, mDpy);
1370 return false;
1371 }
1372
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001373 const bool secureOnly = true;
1374 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1375 mdpOnlyLayersComp(ctx, list, secureOnly);
1376
1377}
1378
1379bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1380 hwc_display_contents_1_t* list, bool secureOnly) {
1381
1382 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1383 return false;
1384
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301385 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1386 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1387 /* Bail out if we are processing only secured video/ui layers
1388 * and we dont have any */
1389 if(secureOnly) {
1390 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1391 return false;
1392 }
1393 /* No Idle fall back for secure video/ui layers and if there is only
1394 * single layer being composed. */
1395 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1396 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1397 return false;
1398 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001399 }
1400
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001401 /* Bail out if we dont have any secure RGB layers */
1402 if (!ctx->listStats[mDpy].secureRGBCount) {
1403 reset(ctx);
1404 return false;
1405 }
1406
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001407 mCurrentFrame.reset(numAppLayers);
1408 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1409
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001410 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001411 /* mark secure RGB layers for MDP comp */
1412 updateSecureRGB(ctx, list);
1413
1414 if(mCurrentFrame.mdpCount == 0) {
1415 reset(ctx);
1416 return false;
1417 }
1418
1419 /* find the maximum batch of layers to be marked for framebuffer */
1420 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1421 if(!ret) {
1422 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1423 reset(ctx);
1424 return false;
1425 }
1426
1427 if(sEnableYUVsplit){
1428 adjustForSourceSplit(ctx, list);
1429 }
1430
1431 if(!postHeuristicsHandling(ctx, list)) {
1432 ALOGD_IF(isDebug(), "post heuristic handling failed");
1433 reset(ctx);
1434 return false;
1435 }
1436
1437 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1438 __FUNCTION__);
1439 return true;
1440}
1441
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001442/* Checks for conditions where YUV layers cannot be bypassed */
1443bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001444 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001445 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001446 return false;
1447 }
1448
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001449 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001450 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1451 return false;
1452 }
1453
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001454 if(isSecuring(ctx, layer)) {
1455 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1456 return false;
1457 }
1458
Saurabh Shah4fdde762013-04-30 18:47:33 -07001459 if(!isValidDimension(ctx, layer)) {
1460 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1461 __FUNCTION__);
1462 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001463 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001464
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001465 if(layer->planeAlpha < 0xFF) {
1466 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1467 in video only mode",
1468 __FUNCTION__);
1469 return false;
1470 }
1471
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001472 return true;
1473}
1474
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001475/* Checks for conditions where Secure RGB layers cannot be bypassed */
1476bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1477 if(isSkipLayer(layer)) {
1478 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1479 __FUNCTION__, mDpy);
1480 return false;
1481 }
1482
1483 if(isSecuring(ctx, layer)) {
1484 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1485 return false;
1486 }
1487
1488 if(not isSupportedForMDPComp(ctx, layer)) {
1489 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1490 __FUNCTION__);
1491 return false;
1492 }
1493 return true;
1494}
1495
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301496/* starts at fromIndex and check for each layer to find
1497 * if it it has overlapping with any Updating layer above it in zorder
1498 * till the end of the batch. returns true if it finds any intersection */
1499bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1500 int fromIndex, int toIndex) {
1501 for(int i = fromIndex; i < toIndex; i++) {
1502 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1503 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1504 return false;
1505 }
1506 }
1507 }
1508 return true;
1509}
1510
1511/* Checks if given layer at targetLayerIndex has any
1512 * intersection with all the updating layers in beween
1513 * fromIndex and toIndex. Returns true if it finds intersectiion */
1514bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1515 int fromIndex, int toIndex, int targetLayerIndex) {
1516 for(int i = fromIndex; i <= toIndex; i++) {
1517 if(!mCurrentFrame.isFBComposed[i]) {
1518 if(areLayersIntersecting(&list->hwLayers[i],
1519 &list->hwLayers[targetLayerIndex])) {
1520 return true;
1521 }
1522 }
1523 }
1524 return false;
1525}
1526
1527int MDPComp::getBatch(hwc_display_contents_1_t* list,
1528 int& maxBatchStart, int& maxBatchEnd,
1529 int& maxBatchCount) {
1530 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301531 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001532 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301533 while (i < mCurrentFrame.layerCount) {
1534 int batchCount = 0;
1535 int batchStart = i;
1536 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001537 /* Adjust batch Z order with the dropped layers so far */
1538 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301539 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301540 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301541 while(i < mCurrentFrame.layerCount) {
1542 if(!mCurrentFrame.isFBComposed[i]) {
1543 if(!batchCount) {
1544 i++;
1545 break;
1546 }
1547 updatingLayersAbove++;
1548 i++;
1549 continue;
1550 } else {
1551 if(mCurrentFrame.drop[i]) {
1552 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001553 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301554 continue;
1555 } else if(updatingLayersAbove <= 0) {
1556 batchCount++;
1557 batchEnd = i;
1558 i++;
1559 continue;
1560 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1561
1562 // We have a valid updating layer already. If layer-i not
1563 // have overlapping with all updating layers in between
1564 // batch-start and i, then we can add layer i to batch.
1565 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1566 batchCount++;
1567 batchEnd = i;
1568 i++;
1569 continue;
1570 } else if(canPushBatchToTop(list, batchStart, i)) {
1571 //If All the non-updating layers with in this batch
1572 //does not have intersection with the updating layers
1573 //above in z-order, then we can safely move the batch to
1574 //higher z-order. Increment fbZ as it is moving up.
1575 if( firstZReverseIndex < 0) {
1576 firstZReverseIndex = i;
1577 }
1578 batchCount++;
1579 batchEnd = i;
1580 fbZ += updatingLayersAbove;
1581 i++;
1582 updatingLayersAbove = 0;
1583 continue;
1584 } else {
1585 //both failed.start the loop again from here.
1586 if(firstZReverseIndex >= 0) {
1587 i = firstZReverseIndex;
1588 }
1589 break;
1590 }
1591 }
1592 }
1593 }
1594 if(batchCount > maxBatchCount) {
1595 maxBatchCount = batchCount;
1596 maxBatchStart = batchStart;
1597 maxBatchEnd = batchEnd;
1598 fbZOrder = fbZ;
1599 }
1600 }
1601 return fbZOrder;
1602}
1603
1604bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1605 hwc_display_contents_1_t* list) {
1606 /* Idea is to keep as many non-updating(cached) layers in FB and
1607 * send rest of them through MDP. This is done in 2 steps.
1608 * 1. Find the maximum contiguous batch of non-updating layers.
1609 * 2. See if we can improve this batch size for caching by adding
1610 * opaque layers around the batch, if they don't have
1611 * any overlapping with the updating layers in between.
1612 * NEVER mark an updating layer for caching.
1613 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001614
1615 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001616 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001617 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301618 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001620 /* Nothing is cached. No batching needed */
1621 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001622 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001623 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001624
1625 /* No MDP comp layers, try to use other comp modes */
1626 if(mCurrentFrame.mdpCount == 0) {
1627 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001628 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001629
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301630 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001631
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301632 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001633 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001634 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001635 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301636 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001637 if(!mCurrentFrame.drop[i]){
1638 //If an unsupported layer is being attempted to
1639 //be pulled out we should fail
1640 if(not isSupportedForMDPComp(ctx, layer)) {
1641 return false;
1642 }
1643 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001644 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001645 }
1646 }
1647
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301648 // update the frame data
1649 mCurrentFrame.fbZ = fbZ;
1650 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001651 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001652 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001653
1654 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301655 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001656
1657 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001659
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001661 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001663 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001665 for(int i = 0; i < numAppLayers; i++) {
1666 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001667 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001668 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001669 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001671 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672 }
1673 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001674
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001675 frame.fbCount = fbCount;
1676 frame.mdpCount = frame.layerCount - frame.fbCount
1677 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001678
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001679 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1680 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681}
1682
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001683// drop other non-AIV layers from external display list.
1684void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001685 hwc_display_contents_1_t* list) {
1686 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1687 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001688 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001689 mCurrentFrame.dropCount++;
1690 mCurrentFrame.drop[i] = true;
1691 }
1692 }
1693 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1694 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1695 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1696 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1697 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1698 mCurrentFrame.dropCount);
1699}
1700
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001701void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001702 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001703 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1704 for(int index = 0;index < nYuvCount; index++){
1705 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1706 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1707
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001708 if(mCurrentFrame.drop[nYuvIndex]) {
1709 continue;
1710 }
1711
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001712 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001713 if(!frame.isFBComposed[nYuvIndex]) {
1714 frame.isFBComposed[nYuvIndex] = true;
1715 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001716 }
1717 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001718 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001719 private_handle_t *hnd = (private_handle_t *)layer->handle;
1720 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001721 frame.isFBComposed[nYuvIndex] = false;
1722 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001723 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001724 }
1725 }
1726 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001727
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001728 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1729 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001730}
1731
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001732void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1733 hwc_display_contents_1_t* list) {
1734 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1735 for(int index = 0;index < nSecureRGBCount; index++){
1736 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1737 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1738
1739 if(!isSecureRGBDoable(ctx, layer)) {
1740 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1741 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1742 mCurrentFrame.fbCount++;
1743 }
1744 } else {
1745 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1746 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1747 mCurrentFrame.fbCount--;
1748 }
1749 }
1750 }
1751
1752 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1753 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1754 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1755 mCurrentFrame.fbCount);
1756}
1757
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001758hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1759 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001760 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001761
1762 /* Update only the region of FB needed for composition */
1763 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1764 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1765 hwc_layer_1_t* layer = &list->hwLayers[i];
1766 hwc_rect_t dst = layer->displayFrame;
1767 fbRect = getUnion(fbRect, dst);
1768 }
1769 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001770 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001771 return fbRect;
1772}
1773
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001774bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1775 hwc_display_contents_1_t* list) {
1776
1777 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001778 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001779 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1780 return false;
1781 }
1782
1783 //Limitations checks
1784 if(!hwLimitationsCheck(ctx, list)) {
1785 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1786 return false;
1787 }
1788
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001789 //Configure framebuffer first if applicable
1790 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001791 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001792 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1793 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001794 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1795 __FUNCTION__);
1796 return false;
1797 }
1798 }
1799
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001800 mCurrentFrame.map();
1801
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001802 if(!allocLayerPipes(ctx, list)) {
1803 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001804 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001805 }
1806
1807 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001808 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001809 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810 int mdpIndex = mCurrentFrame.layerToMDP[index];
1811 hwc_layer_1_t* layer = &list->hwLayers[index];
1812
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301813 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1814 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1815 mdpNextZOrder++;
1816 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001817 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1818 cur_pipe->zOrder = mdpNextZOrder++;
1819
radhakrishnac9a67412013-09-25 17:40:42 +05301820 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301821 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301822 if(configure4k2kYuv(ctx, layer,
1823 mCurrentFrame.mdpToLayer[mdpIndex])
1824 != 0 ){
1825 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1826 for layer %d",__FUNCTION__, index);
1827 return false;
1828 }
1829 else{
1830 mdpNextZOrder++;
1831 }
1832 continue;
1833 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001834 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1835 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301836 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001837 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001838 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001839 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001840 }
1841
Saurabh Shaha36be922013-12-16 18:18:39 -08001842 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1843 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1844 ,__FUNCTION__, mDpy);
1845 return false;
1846 }
1847
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001848 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001849 return true;
1850}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001851
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001852bool MDPComp::resourceCheck(hwc_context_t* ctx,
1853 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001854 const bool fbUsed = mCurrentFrame.fbCount;
1855 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1856 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1857 return false;
1858 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001859
1860 //Will benefit cases where a video has non-updating background.
1861 if((mDpy > HWC_DISPLAY_PRIMARY) and
1862 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1863 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1864 return false;
1865 }
1866
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001867 // Init rotCount to number of rotate sessions used by other displays
1868 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1869 // Count the number of rotator sessions required for current display
1870 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1871 if(!mCurrentFrame.isFBComposed[index]) {
1872 hwc_layer_1_t* layer = &list->hwLayers[index];
1873 private_handle_t *hnd = (private_handle_t *)layer->handle;
1874 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1875 rotCount++;
1876 }
1877 }
1878 }
1879 // if number of layers to rotate exceeds max rotator sessions, bail out.
1880 if(rotCount > RotMgr::MAX_ROT_SESS) {
1881 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1882 __FUNCTION__, mDpy);
1883 return false;
1884 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001885 return true;
1886}
1887
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301888bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1889 hwc_display_contents_1_t* list) {
1890
1891 //A-family hw limitation:
1892 //If a layer need alpha scaling, MDP can not support.
1893 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1894 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1895 if(!mCurrentFrame.isFBComposed[i] &&
1896 isAlphaScaled( &list->hwLayers[i])) {
1897 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1898 return false;
1899 }
1900 }
1901 }
1902
1903 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1904 //If multiple layers requires downscaling and also they are overlapping
1905 //fall back to GPU since MDSS can not handle it.
1906 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1907 qdutils::MDPVersion::getInstance().is8x26()) {
1908 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1909 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1910 if(!mCurrentFrame.isFBComposed[i] &&
1911 isDownscaleRequired(botLayer)) {
1912 //if layer-i is marked for MDP and needs downscaling
1913 //check if any MDP layer on top of i & overlaps with layer-i
1914 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1915 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1916 if(!mCurrentFrame.isFBComposed[j] &&
1917 isDownscaleRequired(topLayer)) {
1918 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1919 topLayer->displayFrame);
1920 if(isValidRect(r))
1921 return false;
1922 }
1923 }
1924 }
1925 }
1926 }
1927 return true;
1928}
1929
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001930// Checks only if videos or single layer(RGB) is updating
1931// which is used for setting dynamic fps or perf hint for single
1932// layer video playback
1933bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1934 hwc_display_contents_1_t* list) {
1935 bool support = false;
1936 FrameInfo frame;
1937 frame.reset(mCurrentFrame.layerCount);
1938 memset(&frame.drop, 0, sizeof(frame.drop));
1939 frame.dropCount = 0;
1940 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1941 updateLayerCache(ctx, list, frame);
1942 updateYUV(ctx, list, false /*secure only*/, frame);
1943 // There are only updating YUV layers or there is single RGB
1944 // Layer(Youtube)
1945 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1946 (frame.layerCount == 1)) {
1947 support = true;
1948 }
1949 return support;
1950}
1951
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301952void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1953 //For primary display, set the dynamic refreshrate
1954 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1955 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301956 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1957 MDPVersion& mdpHw = MDPVersion::getInstance();
1958 if(sIdleFallBack) {
1959 //Set minimum panel refresh rate during idle timeout
1960 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001961 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301962 //Set the new fresh rate, if there is only one updating YUV layer
1963 //or there is one single RGB layer with this request
1964 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1965 }
1966 setRefreshRate(ctx, mDpy, refreshRate);
1967 }
1968}
1969
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001970int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001971 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001972 char property[PROPERTY_VALUE_MAX];
1973
Raj Kamal4393eaa2014-06-06 13:45:20 +05301974 if(!ctx || !list) {
1975 ALOGE("%s: Invalid context or list",__FUNCTION__);
1976 mCachedFrame.reset();
1977 return -1;
1978 }
1979
1980 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001981 if(mDpy == HWC_DISPLAY_PRIMARY) {
1982 sSimulationFlags = 0;
1983 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1984 int currentFlags = atoi(property);
1985 if(currentFlags != sSimulationFlags) {
1986 sSimulationFlags = currentFlags;
1987 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1988 sSimulationFlags, sSimulationFlags);
1989 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001990 }
1991 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001992 // reset PTOR
1993 if(!mDpy)
1994 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001995
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301996 //reset old data
1997 mCurrentFrame.reset(numLayers);
1998 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1999 mCurrentFrame.dropCount = 0;
2000
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302001 //Do not cache the information for next draw cycle.
2002 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2003 ALOGI("%s: Unsupported layer count for mdp composition",
2004 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002005 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302006#ifdef DYNAMIC_FPS
2007 setDynRefreshRate(ctx, list);
2008#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002009 return -1;
2010 }
2011
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002012 // Detect the start of animation and fall back to GPU only once to cache
2013 // all the layers in FB and display FB content untill animation completes.
2014 if(ctx->listStats[mDpy].isDisplayAnimating) {
2015 mCurrentFrame.needsRedraw = false;
2016 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2017 mCurrentFrame.needsRedraw = true;
2018 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2019 }
2020 setMDPCompLayerFlags(ctx, list);
2021 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302022#ifdef DYNAMIC_FPS
2023 setDynRefreshRate(ctx, list);
2024#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002025 ret = -1;
2026 return ret;
2027 } else {
2028 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2029 }
2030
Saurabh Shahb39f8152013-08-22 10:21:44 -07002031 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002032 if(isFrameDoable(ctx)) {
2033 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002034 // if AIV Video mode is enabled, drop all non AIV layers from the
2035 // external display list.
2036 if(ctx->listStats[mDpy].mAIVVideoMode) {
2037 dropNonAIVLayers(ctx, list);
2038 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002039
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002040 // if tryFullFrame fails, try to push all video and secure RGB layers
2041 // to MDP for composition.
2042 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002043 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302044 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002045 setMDPCompLayerFlags(ctx, list);
2046 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002047 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002048 reset(ctx);
2049 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2050 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002051 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002052 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2053 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002054 }
2055 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302056 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2057 enablePartialUpdateForMDP3) {
2058 generateROI(ctx, list);
2059 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2060 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2061 }
2062 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002063 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2064 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002065 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002066 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002067
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002068 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002069 ALOGD("GEOMETRY change: %d",
2070 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002071 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002072 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002073 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002074 }
2075
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002076#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302077 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002078#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002079 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002080
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002081 mCachedFrame.cacheAll(list);
2082 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002083 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002084}
2085
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002086bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302087
2088 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302089 int mdpIndex = mCurrentFrame.layerToMDP[index];
2090 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2091 info.pipeInfo = new MdpYUVPipeInfo;
2092 info.rot = NULL;
2093 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302094
2095 pipe_info.lIndex = ovutils::OV_INVALID;
2096 pipe_info.rIndex = ovutils::OV_INVALID;
2097
Saurabh Shahc62f3982014-03-05 14:28:26 -08002098 Overlay::PipeSpecs pipeSpecs;
2099 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2100 pipeSpecs.needsScaling = true;
2101 pipeSpecs.dpy = mDpy;
2102 pipeSpecs.fb = false;
2103
2104 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302105 if(pipe_info.lIndex == ovutils::OV_INVALID){
2106 bRet = false;
2107 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2108 __FUNCTION__);
2109 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002110 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302111 if(pipe_info.rIndex == ovutils::OV_INVALID){
2112 bRet = false;
2113 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2114 __FUNCTION__);
2115 }
2116 return bRet;
2117}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002118
2119int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2120 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002121 if (ctx->mPtorInfo.isActive()) {
2122 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002123 if (fd < 0) {
2124 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002125 }
2126 }
2127 return fd;
2128}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002129//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002130
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002131void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302132 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002133 //If 4k2k Yuv layer split is possible, and if
2134 //fbz is above 4k2k layer, increment fb zorder by 1
2135 //as we split 4k2k layer and increment zorder for right half
2136 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002137 if(!ctx)
2138 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002139 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302140 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2141 index++) {
2142 if(!mCurrentFrame.isFBComposed[index]) {
2143 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2144 mdpNextZOrder++;
2145 }
2146 mdpNextZOrder++;
2147 hwc_layer_1_t* layer = &list->hwLayers[index];
2148 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302149 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302150 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2151 mCurrentFrame.fbZ += 1;
2152 mdpNextZOrder++;
2153 //As we split 4kx2k yuv layer and program to 2 VG pipes
2154 //(if available) increase mdpcount by 1.
2155 mCurrentFrame.mdpCount++;
2156 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002157 }
2158 }
2159 }
radhakrishnac9a67412013-09-25 17:40:42 +05302160}
2161
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002162/*
2163 * Configures pipe(s) for MDP composition
2164 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002165int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002166 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002167 MdpPipeInfoNonSplit& mdp_info =
2168 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302169 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002170 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002171 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002172
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002173 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2174 __FUNCTION__, layer, zOrder, dest);
2175
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002176 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002177 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002178}
2179
Saurabh Shah88e4d272013-09-03 13:31:29 -07002180bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002181 hwc_display_contents_1_t* list) {
2182 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002183
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002184 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002185
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002186 hwc_layer_1_t* layer = &list->hwLayers[index];
2187 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302188 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002189 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302190 continue;
2191 }
2192 }
2193
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002194 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002195 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002196 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002197 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002198 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002199
Saurabh Shahc62f3982014-03-05 14:28:26 -08002200 Overlay::PipeSpecs pipeSpecs;
2201 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2202 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2203 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2204 (qdutils::MDPVersion::getInstance().is8x26() and
2205 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2206 pipeSpecs.dpy = mDpy;
2207 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002208 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002209
Saurabh Shahc62f3982014-03-05 14:28:26 -08002210 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2211
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002212 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002213 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002214 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002215 }
2216 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002217 return true;
2218}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002219
radhakrishnac9a67412013-09-25 17:40:42 +05302220int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2221 PipeLayerPair& PipeLayerPair) {
2222 MdpYUVPipeInfo& mdp_info =
2223 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2224 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302225 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302226 eDest lDest = mdp_info.lIndex;
2227 eDest rDest = mdp_info.rIndex;
2228
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002229 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302230 lDest, rDest, &PipeLayerPair.rot);
2231}
2232
Saurabh Shah88e4d272013-09-03 13:31:29 -07002233bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002234
Raj Kamal4393eaa2014-06-06 13:45:20 +05302235 if(!isEnabled() or !mModeOn) {
2236 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302237 return true;
2238 }
2239
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002240 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002241 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002242 sHandleTimeout = true;
2243 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002244
2245 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002246 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002247
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002248 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2249 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002250 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002251 if(mCurrentFrame.isFBComposed[i]) continue;
2252
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002253 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002254 private_handle_t *hnd = (private_handle_t *)layer->handle;
2255 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002256 if (!(layer->flags & HWC_COLOR_FILL)) {
2257 ALOGE("%s handle null", __FUNCTION__);
2258 return false;
2259 }
2260 // No PLAY for Color layer
2261 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2262 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002263 }
2264
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002265 int mdpIndex = mCurrentFrame.layerToMDP[i];
2266
Raj Kamal389d6e32014-08-04 14:43:24 +05302267 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302268 {
2269 MdpYUVPipeInfo& pipe_info =
2270 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2271 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2272 ovutils::eDest indexL = pipe_info.lIndex;
2273 ovutils::eDest indexR = pipe_info.rIndex;
2274 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302275 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302276 if(rot) {
2277 rot->queueBuffer(fd, offset);
2278 fd = rot->getDstMemId();
2279 offset = rot->getDstOffset();
2280 }
2281 if(indexL != ovutils::OV_INVALID) {
2282 ovutils::eDest destL = (ovutils::eDest)indexL;
2283 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2284 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2285 if (!ov.queueBuffer(fd, offset, destL)) {
2286 ALOGE("%s: queueBuffer failed for display:%d",
2287 __FUNCTION__, mDpy);
2288 return false;
2289 }
2290 }
2291
2292 if(indexR != ovutils::OV_INVALID) {
2293 ovutils::eDest destR = (ovutils::eDest)indexR;
2294 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2295 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2296 if (!ov.queueBuffer(fd, offset, destR)) {
2297 ALOGE("%s: queueBuffer failed for display:%d",
2298 __FUNCTION__, mDpy);
2299 return false;
2300 }
2301 }
2302 }
2303 else{
2304 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002305 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302306 ovutils::eDest dest = pipe_info.index;
2307 if(dest == ovutils::OV_INVALID) {
2308 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002309 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302310 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002311
radhakrishnac9a67412013-09-25 17:40:42 +05302312 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2313 continue;
2314 }
2315
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002316 int fd = hnd->fd;
2317 uint32_t offset = (uint32_t)hnd->offset;
2318 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2319 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002320 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002321 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002322 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002323 }
2324
radhakrishnac9a67412013-09-25 17:40:42 +05302325 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2326 using pipe: %d", __FUNCTION__, layer,
2327 hnd, dest );
2328
radhakrishnac9a67412013-09-25 17:40:42 +05302329 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2330 if(rot) {
2331 if(!rot->queueBuffer(fd, offset))
2332 return false;
2333 fd = rot->getDstMemId();
2334 offset = rot->getDstOffset();
2335 }
2336
2337 if (!ov.queueBuffer(fd, offset, dest)) {
2338 ALOGE("%s: queueBuffer failed for display:%d ",
2339 __FUNCTION__, mDpy);
2340 return false;
2341 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002342 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002343
2344 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002345 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002346 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002347}
2348
Saurabh Shah88e4d272013-09-03 13:31:29 -07002349//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002350
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002351void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302352 hwc_display_contents_1_t* list){
2353 //if 4kx2k yuv layer is totally present in either in left half
2354 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302355 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302356 if(mCurrentFrame.fbZ >= 0) {
2357 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2358 index++) {
2359 if(!mCurrentFrame.isFBComposed[index]) {
2360 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2361 mdpNextZOrder++;
2362 }
2363 mdpNextZOrder++;
2364 hwc_layer_1_t* layer = &list->hwLayers[index];
2365 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302366 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302367 hwc_rect_t dst = layer->displayFrame;
2368 if((dst.left > lSplit) || (dst.right < lSplit)) {
2369 mCurrentFrame.mdpCount += 1;
2370 }
2371 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2372 mCurrentFrame.fbZ += 1;
2373 mdpNextZOrder++;
2374 }
2375 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002376 }
radhakrishnac9a67412013-09-25 17:40:42 +05302377 }
2378}
2379
Saurabh Shah88e4d272013-09-03 13:31:29 -07002380bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002381 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002382
Saurabh Shahc62f3982014-03-05 14:28:26 -08002383 const int lSplit = getLeftSplit(ctx, mDpy);
2384 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002385 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002386 pipe_info.lIndex = ovutils::OV_INVALID;
2387 pipe_info.rIndex = ovutils::OV_INVALID;
2388
Saurabh Shahc62f3982014-03-05 14:28:26 -08002389 Overlay::PipeSpecs pipeSpecs;
2390 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2391 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2392 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2393 pipeSpecs.dpy = mDpy;
2394 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2395 pipeSpecs.fb = false;
2396
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002397 // Acquire pipe only for the updating half
2398 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2399 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2400
2401 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002402 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002403 if(pipe_info.lIndex == ovutils::OV_INVALID)
2404 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002405 }
2406
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002407 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002408 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2409 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002410 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002411 return false;
2412 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002413
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002414 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002415}
2416
Saurabh Shah88e4d272013-09-03 13:31:29 -07002417bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002418 hwc_display_contents_1_t* list) {
2419 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002420
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002421 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002422
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002423 hwc_layer_1_t* layer = &list->hwLayers[index];
2424 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302425 hwc_rect_t dst = layer->displayFrame;
2426 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302427 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302428 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002429 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302430 continue;
2431 }
2432 }
2433 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002434 int mdpIndex = mCurrentFrame.layerToMDP[index];
2435 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002436 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002437 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002438 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002439
Saurabh Shahc62f3982014-03-05 14:28:26 -08002440 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2441 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2442 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002443 return false;
2444 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002445 }
2446 return true;
2447}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002448
radhakrishnac9a67412013-09-25 17:40:42 +05302449int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2450 PipeLayerPair& PipeLayerPair) {
2451 const int lSplit = getLeftSplit(ctx, mDpy);
2452 hwc_rect_t dst = layer->displayFrame;
2453 if((dst.left > lSplit)||(dst.right < lSplit)){
2454 MdpYUVPipeInfo& mdp_info =
2455 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2456 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302457 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302458 eDest lDest = mdp_info.lIndex;
2459 eDest rDest = mdp_info.rIndex;
2460
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002461 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302462 lDest, rDest, &PipeLayerPair.rot);
2463 }
2464 else{
2465 return configure(ctx, layer, PipeLayerPair);
2466 }
2467}
2468
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002469/*
2470 * Configures pipe(s) for MDP composition
2471 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002472int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002473 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002474 MdpPipeInfoSplit& mdp_info =
2475 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002476 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302477 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002478 eDest lDest = mdp_info.lIndex;
2479 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002480
2481 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002482 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002483
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002484 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002485 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002486}
2487
Saurabh Shah88e4d272013-09-03 13:31:29 -07002488bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002489
Raj Kamal4393eaa2014-06-06 13:45:20 +05302490 if(!isEnabled() or !mModeOn) {
2491 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302492 return true;
2493 }
2494
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002495 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002496 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002497 sHandleTimeout = true;
2498 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002499
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002500 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002501 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002502
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002503 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2504 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002505 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002506 if(mCurrentFrame.isFBComposed[i]) continue;
2507
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002508 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002509 private_handle_t *hnd = (private_handle_t *)layer->handle;
2510 if(!hnd) {
2511 ALOGE("%s handle null", __FUNCTION__);
2512 return false;
2513 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002514
2515 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2516 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002517 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002518
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002519 int mdpIndex = mCurrentFrame.layerToMDP[i];
2520
Raj Kamal389d6e32014-08-04 14:43:24 +05302521 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302522 {
2523 MdpYUVPipeInfo& pipe_info =
2524 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2525 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2526 ovutils::eDest indexL = pipe_info.lIndex;
2527 ovutils::eDest indexR = pipe_info.rIndex;
2528 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302529 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302530 if(rot) {
2531 rot->queueBuffer(fd, offset);
2532 fd = rot->getDstMemId();
2533 offset = rot->getDstOffset();
2534 }
2535 if(indexL != ovutils::OV_INVALID) {
2536 ovutils::eDest destL = (ovutils::eDest)indexL;
2537 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2538 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2539 if (!ov.queueBuffer(fd, offset, destL)) {
2540 ALOGE("%s: queueBuffer failed for display:%d",
2541 __FUNCTION__, mDpy);
2542 return false;
2543 }
2544 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002545
radhakrishnac9a67412013-09-25 17:40:42 +05302546 if(indexR != ovutils::OV_INVALID) {
2547 ovutils::eDest destR = (ovutils::eDest)indexR;
2548 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2549 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2550 if (!ov.queueBuffer(fd, offset, destR)) {
2551 ALOGE("%s: queueBuffer failed for display:%d",
2552 __FUNCTION__, mDpy);
2553 return false;
2554 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002555 }
2556 }
radhakrishnac9a67412013-09-25 17:40:42 +05302557 else{
2558 MdpPipeInfoSplit& pipe_info =
2559 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2560 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002561
radhakrishnac9a67412013-09-25 17:40:42 +05302562 ovutils::eDest indexL = pipe_info.lIndex;
2563 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002564
radhakrishnac9a67412013-09-25 17:40:42 +05302565 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002566 uint32_t offset = (uint32_t)hnd->offset;
2567 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2568 if (!mDpy && (index != -1)) {
2569 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2570 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002571 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002572 }
radhakrishnac9a67412013-09-25 17:40:42 +05302573
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002574 if(ctx->mAD->draw(ctx, fd, offset)) {
2575 fd = ctx->mAD->getDstFd();
2576 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002577 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002578
radhakrishnac9a67412013-09-25 17:40:42 +05302579 if(rot) {
2580 rot->queueBuffer(fd, offset);
2581 fd = rot->getDstMemId();
2582 offset = rot->getDstOffset();
2583 }
2584
2585 //************* play left mixer **********
2586 if(indexL != ovutils::OV_INVALID) {
2587 ovutils::eDest destL = (ovutils::eDest)indexL;
2588 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2589 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2590 if (!ov.queueBuffer(fd, offset, destL)) {
2591 ALOGE("%s: queueBuffer failed for left mixer",
2592 __FUNCTION__);
2593 return false;
2594 }
2595 }
2596
2597 //************* play right mixer **********
2598 if(indexR != ovutils::OV_INVALID) {
2599 ovutils::eDest destR = (ovutils::eDest)indexR;
2600 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2601 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2602 if (!ov.queueBuffer(fd, offset, destR)) {
2603 ALOGE("%s: queueBuffer failed for right mixer",
2604 __FUNCTION__);
2605 return false;
2606 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002607 }
2608 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002609
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002610 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2611 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002612
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002613 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002614}
Saurabh Shahab47c692014-02-12 18:45:57 -08002615
2616//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002617
2618bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2619 hwc_display_contents_1_t* list) {
2620 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2621 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2622
2623 for(int i = numAppLayers - 1; i >= 0; i--) {
2624 if(!isValidRect(visibleRect)) {
2625 mCurrentFrame.drop[i] = true;
2626 mCurrentFrame.dropCount++;
2627 continue;
2628 }
2629
2630 const hwc_layer_1_t* layer = &list->hwLayers[i];
2631 hwc_rect_t dstRect = layer->displayFrame;
2632 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2633
2634 if(!isValidRect(res)) {
2635 mCurrentFrame.drop[i] = true;
2636 mCurrentFrame.dropCount++;
2637 } else {
2638 /* Reset frame ROI when any layer which needs scaling also needs ROI
2639 * cropping */
2640 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2641 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2642 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2643 mCurrentFrame.dropCount = 0;
2644 return false;
2645 }
2646
2647 /* deduct any opaque region from visibleRect */
2648 if (layer->blending == HWC_BLENDING_NONE &&
2649 layer->planeAlpha == 0xFF)
2650 visibleRect = deductRect(visibleRect, res);
2651 }
2652 }
2653 return true;
2654}
2655
2656/*
2657 * HW Limitation: ping pong split can always split the ping pong output
2658 * equally across two DSI's. So the ROI programmed should be of equal width
2659 * for both the halves
2660 */
2661void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2662 hwc_display_contents_1_t* list) {
2663 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2664
2665
2666 if(!canPartialUpdate(ctx, list))
2667 return;
2668
2669 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2670 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2671 (int)ctx->dpyAttr[mDpy].yres};
2672
2673 for(int index = 0; index < numAppLayers; index++ ) {
2674 hwc_layer_1_t* layer = &list->hwLayers[index];
2675
2676 // If we have a RGB layer which needs rotation, no partial update
2677 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2678 return;
2679
2680 if ((mCachedFrame.hnd[index] != layer->handle) ||
2681 isYuvBuffer((private_handle_t *)layer->handle)) {
2682 hwc_rect_t dst = layer->displayFrame;
2683 hwc_rect_t updatingRect = dst;
2684
2685#ifdef QCOM_BSP
2686 if(!needsScaling(layer) && !layer->transform)
2687 {
2688 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2689 int x_off = dst.left - src.left;
2690 int y_off = dst.top - src.top;
2691 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2692 }
2693#endif
2694
2695 roi = getUnion(roi, updatingRect);
2696 }
2697 }
2698
2699 /* No layer is updating. Still SF wants a refresh.*/
2700 if(!isValidRect(roi))
2701 return;
2702
2703 roi = expandROIFromMidPoint(roi, fullFrame);
2704
2705 hwc_rect lFrame = fullFrame;
2706 lFrame.right /= 2;
2707 hwc_rect lRoi = getIntersection(roi, lFrame);
2708
2709 // Align ROI coordinates to panel restrictions
2710 lRoi = getSanitizeROI(lRoi, lFrame);
2711
2712 hwc_rect rFrame = fullFrame;
2713 rFrame.left = lFrame.right;
2714 hwc_rect rRoi = getIntersection(roi, rFrame);
2715
2716 // Align ROI coordinates to panel restrictions
2717 rRoi = getSanitizeROI(rRoi, rFrame);
2718
2719 roi = getUnion(lRoi, rRoi);
2720
2721 ctx->listStats[mDpy].lRoi = roi;
2722 if(!validateAndApplyROI(ctx, list))
2723 resetROI(ctx, mDpy);
2724
2725 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2726 __FUNCTION__,
2727 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2728 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2729 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2730 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2731}
2732
Saurabh Shahab47c692014-02-12 18:45:57 -08002733bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002734 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002735 private_handle_t *hnd = (private_handle_t *)layer->handle;
2736 hwc_rect_t dst = layer->displayFrame;
2737 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2738 pipe_info.lIndex = ovutils::OV_INVALID;
2739 pipe_info.rIndex = ovutils::OV_INVALID;
2740
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002741 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2742 trimAgainstROI(ctx,crop, dst);
2743
Saurabh Shahab47c692014-02-12 18:45:57 -08002744 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2745 //should have a higher priority than the right one. Pipe priorities are
2746 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002747
Saurabh Shahc62f3982014-03-05 14:28:26 -08002748 Overlay::PipeSpecs pipeSpecs;
2749 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2750 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2751 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2752 pipeSpecs.dpy = mDpy;
2753 pipeSpecs.fb = false;
2754
Saurabh Shahab47c692014-02-12 18:45:57 -08002755 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002756 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002757 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002758 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002759 }
2760
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002761 /* Use 2 pipes IF
2762 a) Layer's crop width is > 2048 or
2763 b) Layer's dest width > 2048 or
2764 c) On primary, driver has indicated with caps to split always. This is
2765 based on an empirically derived value of panel height. Applied only
2766 if the layer's width is > mixer's width
2767 */
2768
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302769 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002770 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302771 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002772 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2773 const uint32_t dstWidth = dst.right - dst.left;
2774 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002775 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002776 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002777 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002778 crop.bottom - crop.top;
2779 //Approximation to actual clock, ignoring the common factors in pipe and
2780 //mixer cases like line_time
2781 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2782 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002783
Saurabh Shah05f4e222015-02-05 14:36:22 -08002784 const uint32_t downscale = getRotDownscale(ctx, layer);
2785 if(downscale) {
2786 cropWidth /= downscale;
2787 cropHeight /= downscale;
2788 }
2789
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002790 if(dstWidth > mdpHw.getMaxPipeWidth() or
2791 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002792 (primarySplitAlways and
2793 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002794 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002795 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002796 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002797 }
2798
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002799 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2800 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002801 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002802 }
2803 }
2804
2805 return true;
2806}
2807
Saurabh Shahab47c692014-02-12 18:45:57 -08002808int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2809 PipeLayerPair& PipeLayerPair) {
2810 private_handle_t *hnd = (private_handle_t *)layer->handle;
2811 if(!hnd) {
2812 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2813 return -1;
2814 }
2815 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2816 MdpPipeInfoSplit& mdp_info =
2817 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2818 Rotator **rot = &PipeLayerPair.rot;
2819 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002820 eDest lDest = mdp_info.lIndex;
2821 eDest rDest = mdp_info.rIndex;
2822 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2823 hwc_rect_t dst = layer->displayFrame;
2824 int transform = layer->transform;
2825 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002826 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002827 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002828 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2829
2830 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2831 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2832
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002833 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2834 /* MDP driver crops layer coordinates against ROI in Non-Split
2835 * and Split MDP comp. But HWC needs to crop them for source split.
2836 * Reason: 1) Source split is efficient only when the final effective
2837 * load is distributed evenly across mixers.
2838 * 2) We have to know the effective width of the layer that
2839 * the ROI needs to find the no. of pipes the layer needs.
2840 */
2841 trimAgainstROI(ctx, crop, dst);
2842 }
2843
Saurabh Shahab47c692014-02-12 18:45:57 -08002844 // Handle R/B swap
2845 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2846 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2847 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2848 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2849 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2850 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002851 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002852 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2853 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002854 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002855 /* Calculate the external display position based on MDP downscale,
2856 ActionSafe, and extorientation features. */
2857 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002858
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002859 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302860 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002861 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002862
2863 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2864 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002865 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002866 }
2867
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002868 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002869 (*rot) = ctx->mRotMgr->getNext();
2870 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002871 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002872 //If the video is using a single pipe, enable BWC
2873 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002874 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2875 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002876 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002877 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002878 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002879 ALOGE("%s: configRotator failed!", __FUNCTION__);
2880 return -1;
2881 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002882 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002883 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002884 }
2885
2886 //If 2 pipes being used, divide layer into half, crop and dst
2887 hwc_rect_t cropL = crop;
2888 hwc_rect_t cropR = crop;
2889 hwc_rect_t dstL = dst;
2890 hwc_rect_t dstR = dst;
2891 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2892 cropL.right = (crop.right + crop.left) / 2;
2893 cropR.left = cropL.right;
2894 sanitizeSourceCrop(cropL, cropR, hnd);
2895
Saurabh Shahb729b192014-08-15 18:04:24 -07002896 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002897 //Swap crops on H flip since 2 pipes are being used
2898 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2899 hwc_rect_t tmp = cropL;
2900 cropL = cropR;
2901 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002902 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002903 }
2904
Saurabh Shahb729b192014-08-15 18:04:24 -07002905 //cropSwap trick: If the src and dst widths are both odd, let us say
2906 //2507, then splitting both into half would cause left width to be 1253
2907 //and right 1254. If crop is swapped because of H flip, this will cause
2908 //left crop width to be 1254, whereas left dst width remains 1253, thus
2909 //inducing a scaling that is unaccounted for. To overcome that we add 1
2910 //to the dst width if there is a cropSwap. So if the original width was
2911 //2507, the left dst width will be 1254. Even if the original width was
2912 //even for ex: 2508, the left dst width will still remain 1254.
2913 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002914 dstR.left = dstL.right;
2915 }
2916
2917 //For the mdp, since either we are pre-rotating or MDP does flips
2918 orient = OVERLAY_TRANSFORM_0;
2919 transform = 0;
2920
2921 //configure left pipe
2922 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002923 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002924 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2925 (ovutils::eBlending) getBlending(layer->blending));
2926
2927 if(configMdp(ctx->mOverlay, pargL, orient,
2928 cropL, dstL, metadata, lDest) < 0) {
2929 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2930 return -1;
2931 }
2932 }
2933
2934 //configure right pipe
2935 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002936 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002937 static_cast<eRotFlags>(rotFlags),
2938 layer->planeAlpha,
2939 (ovutils::eBlending) getBlending(layer->blending));
2940 if(configMdp(ctx->mOverlay, pargR, orient,
2941 cropR, dstR, metadata, rDest) < 0) {
2942 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2943 return -1;
2944 }
2945 }
2946
2947 return 0;
2948}
2949
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002950bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2951 Locker::Autolock _l(ctx->mDrawLock);
2952 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2953 char path[MAX_SYSFS_FILE_PATH];
2954 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2955 int fd = open(path, O_RDONLY);
2956 if(fd < 0) {
2957 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2958 return -1;
2959 }
2960 char value[4];
2961 ssize_t size_read = read(fd, value, sizeof(value)-1);
2962 if(size_read <= 0) {
2963 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2964 close(fd);
2965 return -1;
2966 }
2967 close(fd);
2968 value[size_read] = '\0';
2969 return atoi(value);
2970}
2971
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002972int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2973 Locker::Autolock _l(ctx->mDrawLock);
2974 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2975 char path[MAX_SYSFS_FILE_PATH];
2976 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2977 int fd = open(path, O_WRONLY);
2978 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002979 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002980 return -1;
2981 }
2982 char value[4];
2983 snprintf(value, sizeof(value), "%d", (int)enable);
2984 ssize_t ret = write(fd, value, strlen(value));
2985 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002986 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002987 close(fd);
2988 return -1;
2989 }
2990 close(fd);
2991 sIsPartialUpdateActive = enable;
2992 return 0;
2993}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002994
2995bool MDPComp::loadPerfLib() {
2996 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2997 bool success = false;
2998 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2999 ALOGE("vendor library not set in ro.vendor.extension_library");
3000 return false;
3001 }
3002
3003 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3004 if(sLibPerfHint) {
3005 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3006 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3007 if (!sPerfLockAcquire || !sPerfLockRelease) {
3008 ALOGE("Failed to load symbols for perfLock");
3009 dlclose(sLibPerfHint);
3010 sLibPerfHint = NULL;
3011 return false;
3012 }
3013 success = true;
3014 ALOGI("Successfully Loaded perf hint API's");
3015 } else {
3016 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3017 }
3018 return success;
3019}
3020
3021void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3022 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3023 return;
3024 }
3025 static int count = sPerfHintWindow;
3026 static int perflockFlag = 0;
3027
3028 /* Send hint to mpctl when single layer is updated
3029 * for a successful number of windows. Hint release
3030 * happens immediately upon multiple layer update.
3031 */
3032 if (onlyVideosUpdating(ctx, list)) {
3033 if(count) {
3034 count--;
3035 }
3036 } else {
3037 if (perflockFlag) {
3038 perflockFlag = 0;
3039 sPerfLockRelease(sPerfLockHandle);
3040 }
3041 count = sPerfHintWindow;
3042 }
3043 if (count == 0 && !perflockFlag) {
3044 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3045 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3046 &perfHint, sizeof(perfHint)/sizeof(int));
3047 if(sPerfLockHandle < 0) {
3048 ALOGE("Perf Lock Acquire Failed");
3049 } else {
3050 perflockFlag = 1;
3051 }
3052 }
3053}
3054
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003055}; //namespace
3056