blob: 3d3812c39a12b4e30e0237615c862b218c9c9e06 [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
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500809 // No MDP composition for 3D
810 if(needs3DComposition(ctx, mDpy))
811 return false;
812
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700813 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800814 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700815 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800816 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
817 return false;
818 }
819
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800820 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800821 hwc_layer_1_t* layer = &list->hwLayers[i];
822 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800823
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800824 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700825 if(!canUseRotator(ctx, mDpy)) {
826 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
827 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700828 return false;
829 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800830 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530831
832 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
833 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800834 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700835 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530836 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
837 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
838 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800839 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700840
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700841 if(ctx->mAD->isDoable()) {
842 return false;
843 }
844
Saurabh Shahaa236822013-04-24 18:07:26 -0700845 //If all above hard conditions are met we can do full or partial MDP comp.
846 bool ret = false;
847 if(fullMDPComp(ctx, list)) {
848 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700849 } else if(fullMDPCompWithPTOR(ctx, list)) {
850 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700851 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700852 ret = true;
853 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530854
Saurabh Shahaa236822013-04-24 18:07:26 -0700855 return ret;
856}
857
858bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700859
860 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
861 return false;
862
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700863 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
864 for(int i = 0; i < numAppLayers; i++) {
865 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700866 if(not mCurrentFrame.drop[i] and
867 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700868 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
869 return false;
870 }
871 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800872
Saurabh Shahaa236822013-04-24 18:07:26 -0700873 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700874 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
875 sizeof(mCurrentFrame.isFBComposed));
876 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
877 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700878
Raj Kamal389d6e32014-08-04 14:43:24 +0530879 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800880 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530881 }
882
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800883 if(!postHeuristicsHandling(ctx, list)) {
884 ALOGD_IF(isDebug(), "post heuristic handling failed");
885 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700886 return false;
887 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700888 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
889 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700890 return true;
891}
892
Sushil Chauhandefd3522014-05-13 18:17:12 -0700893/* Full MDP Composition with Peripheral Tiny Overlap Removal.
894 * MDP bandwidth limitations can be avoided, if the overlap region
895 * covered by the smallest layer at a higher z-order, gets composed
896 * by Copybit on a render buffer, which can be queued to MDP.
897 */
898bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
899 hwc_display_contents_1_t* list) {
900
901 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
902 const int stagesForMDP = min(sMaxPipesPerMixer,
903 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
904
905 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700906 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700907 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
908 return false;
909 }
910
911 // Frame level checks
912 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
913 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
914 isSecurePresent(ctx, mDpy)) {
915 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
916 return false;
917 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700918 // MDP comp checks
919 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700920 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700921 if(not isSupportedForMDPComp(ctx, layer)) {
922 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
923 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700924 }
925 }
926
Sushil Chauhandefd3522014-05-13 18:17:12 -0700927 /* We cannot use this composition mode, if:
928 1. A below layer needs scaling.
929 2. Overlap is not peripheral to display.
930 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700931 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700932 */
933
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700934 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
935 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
936 memset(overlapRect, 0, sizeof(overlapRect));
937 int layerPixelCount, minPixelCount = 0;
938 int numPTORLayersFound = 0;
939 for (int i = numAppLayers-1; (i >= 0 &&
940 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700941 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700942 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700943 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700944 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
945 // PTOR layer should be peripheral and cannot have transform
946 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
947 has90Transform(layer)) {
948 continue;
949 }
950 if((3 * (layerPixelCount + minPixelCount)) >
951 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
952 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
953 continue;
954 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700955 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 for (int j = i-1; j >= 0; j--) {
957 // Check if the layers below this layer qualifies for PTOR comp
958 hwc_layer_1_t* layer = &list->hwLayers[j];
959 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700960 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700961 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700962 if (isValidRect(getIntersection(dispFrame, disFrame))) {
963 if (has90Transform(layer) || needsScaling(layer)) {
964 found = false;
965 break;
966 }
967 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700968 }
969 }
970 // Store the minLayer Index
971 if(found) {
972 minLayerIndex[numPTORLayersFound] = i;
973 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
974 minPixelCount += layerPixelCount;
975 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700976 }
977 }
978
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700979 // No overlap layers
980 if (!numPTORLayersFound)
981 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700982
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 // Store the displayFrame and the sourceCrops of the layers
984 hwc_rect_t displayFrame[numAppLayers];
985 hwc_rect_t sourceCrop[numAppLayers];
986 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700987 hwc_layer_1_t* layer = &list->hwLayers[i];
988 displayFrame[i] = layer->displayFrame;
989 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700990 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700991
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530992 /**
993 * It's possible that 2 PTOR layers might have overlapping.
994 * In such case, remove the intersection(again if peripheral)
995 * from the lower PTOR layer to avoid overlapping.
996 * If intersection is not on peripheral then compromise
997 * by reducing number of PTOR layers.
998 **/
999 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1000 if(isValidRect(commonRect)) {
1001 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1002 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1003 }
1004
1005 ctx->mPtorInfo.count = numPTORLayersFound;
1006 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1007 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1008 }
1009
1010 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1011 // reset PTOR
1012 ctx->mPtorInfo.count = 0;
1013 if(isValidRect(commonRect)) {
1014 // If PTORs are intersecting restore displayframe of PTOR[1]
1015 // before returning, as we have modified it above.
1016 list->hwLayers[minLayerIndex[1]].displayFrame =
1017 displayFrame[minLayerIndex[1]];
1018 }
1019 return false;
1020 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001021 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1022 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1023
Xu Yangcda012c2014-07-30 21:57:21 +08001024 // Store the blending mode, planeAlpha, and transform of PTOR layers
1025 int32_t blending[numPTORLayersFound];
1026 uint8_t planeAlpha[numPTORLayersFound];
1027 uint32_t transform[numPTORLayersFound];
1028
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001029 for(int j = 0; j < numPTORLayersFound; j++) {
1030 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001031
1032 // Update src crop of PTOR layer
1033 hwc_layer_1_t* layer = &list->hwLayers[index];
1034 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1035 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1036 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1037 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1038
1039 // Store & update w, h, format of PTOR layer
1040 private_handle_t *hnd = (private_handle_t *)layer->handle;
1041 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1042 layerWhf[j] = whf;
1043 hnd->width = renderBuf->width;
1044 hnd->height = renderBuf->height;
1045 hnd->format = renderBuf->format;
1046
Xu Yangcda012c2014-07-30 21:57:21 +08001047 // Store & update blending mode, planeAlpha and transform of PTOR layer
1048 blending[j] = layer->blending;
1049 planeAlpha[j] = layer->planeAlpha;
1050 transform[j] = layer->transform;
1051 layer->blending = HWC_BLENDING_NONE;
1052 layer->planeAlpha = 0xFF;
1053 layer->transform = 0;
1054
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001055 // Remove overlap from crop & displayFrame of below layers
1056 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001057 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001058 if(!isValidRect(getIntersection(layer->displayFrame,
1059 overlapRect[j]))) {
1060 continue;
1061 }
1062 // Update layer attributes
1063 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1064 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301065 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001066 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1067 layer->transform);
1068 layer->sourceCropf.left = (float)srcCrop.left;
1069 layer->sourceCropf.top = (float)srcCrop.top;
1070 layer->sourceCropf.right = (float)srcCrop.right;
1071 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1072 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001073 }
1074
1075 mCurrentFrame.mdpCount = numAppLayers;
1076 mCurrentFrame.fbCount = 0;
1077 mCurrentFrame.fbZ = -1;
1078
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301079 for (int j = 0; j < numAppLayers; j++) {
1080 if(isValidRect(list->hwLayers[j].displayFrame)) {
1081 mCurrentFrame.isFBComposed[j] = false;
1082 } else {
1083 mCurrentFrame.mdpCount--;
1084 mCurrentFrame.drop[j] = true;
1085 }
1086 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001087
1088 bool result = postHeuristicsHandling(ctx, list);
1089
1090 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001091 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001092 hwc_layer_1_t* layer = &list->hwLayers[i];
1093 layer->displayFrame = displayFrame[i];
1094 layer->sourceCropf.left = (float)sourceCrop[i].left;
1095 layer->sourceCropf.top = (float)sourceCrop[i].top;
1096 layer->sourceCropf.right = (float)sourceCrop[i].right;
1097 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1098 }
1099
Xu Yangcda012c2014-07-30 21:57:21 +08001100 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001101 for (int i = 0; i < numPTORLayersFound; i++) {
1102 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001103 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001104 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1105 hnd->width = layerWhf[i].w;
1106 hnd->height = layerWhf[i].h;
1107 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001108 layer->blending = blending[i];
1109 layer->planeAlpha = planeAlpha[i];
1110 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001111 }
1112
Sushil Chauhandefd3522014-05-13 18:17:12 -07001113 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001114 // reset PTOR
1115 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001116 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001117 } else {
1118 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1119 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001120 }
1121
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001122 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1123 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001124 return result;
1125}
1126
Saurabh Shahaa236822013-04-24 18:07:26 -07001127bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1128{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001129 if(!sEnableMixedMode) {
1130 //Mixed mode is disabled. No need to even try caching.
1131 return false;
1132 }
1133
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001134 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301135 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1136 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001137 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001138 cacheBasedComp(ctx, list);
1139 } else {
1140 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001141 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001142 }
1143
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001144 return ret;
1145}
1146
1147bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1148 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001149 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1150 return false;
1151
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001152 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001153 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001154 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001155
1156 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1157 for(int i = 0; i < numAppLayers; i++) {
1158 if(!mCurrentFrame.isFBComposed[i]) {
1159 hwc_layer_1_t* layer = &list->hwLayers[i];
1160 if(not isSupportedForMDPComp(ctx, layer)) {
1161 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1162 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001163 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001164 return false;
1165 }
1166 }
1167 }
1168
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001169 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001170 /* mark secure RGB layers for MDP comp */
1171 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301172 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001173 if(!ret) {
1174 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001175 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001176 return false;
1177 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001178
1179 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001180
Raj Kamal389d6e32014-08-04 14:43:24 +05301181 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001182 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301183 }
1184
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001185 if(!postHeuristicsHandling(ctx, list)) {
1186 ALOGD_IF(isDebug(), "post heuristic handling failed");
1187 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001188 return false;
1189 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001190 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1191 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001192
Saurabh Shahaa236822013-04-24 18:07:26 -07001193 return true;
1194}
1195
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001196bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001197 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001198 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1199 return false;
1200
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001201 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001202 return false;
1203 }
1204
Saurabh Shahb772ae32013-11-18 15:40:02 -08001205 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001206 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1207 const int stagesForMDP = min(sMaxPipesPerMixer,
1208 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001209
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001210 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1211 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1212 int lastMDPSupportedIndex = numAppLayers;
1213 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001214
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001215 //Find the minimum MDP batch size
1216 for(int i = 0; i < numAppLayers;i++) {
1217 if(mCurrentFrame.drop[i]) {
1218 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001219 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001220 }
1221 hwc_layer_1_t* layer = &list->hwLayers[i];
1222 if(not isSupportedForMDPComp(ctx, layer)) {
1223 lastMDPSupportedIndex = i;
1224 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1225 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001226 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001227 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001228 }
1229
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001230 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1231 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1232 mCurrentFrame.dropCount);
1233
1234 //Start at a point where the fb batch should at least have 2 layers, for
1235 //this mode to be justified.
1236 while(fbBatchSize < 2) {
1237 ++fbBatchSize;
1238 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001239 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001240
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001241 //If there are no layers for MDP, this mode doesnt make sense.
1242 if(mdpBatchSize < 1) {
1243 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1244 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001245 return false;
1246 }
1247
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001248 mCurrentFrame.reset(numAppLayers);
1249
1250 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1251 while(mdpBatchSize > 0) {
1252 //Mark layers for MDP comp
1253 int mdpBatchLeft = mdpBatchSize;
1254 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1255 if(mCurrentFrame.drop[i]) {
1256 continue;
1257 }
1258 mCurrentFrame.isFBComposed[i] = false;
1259 --mdpBatchLeft;
1260 }
1261
1262 mCurrentFrame.fbZ = mdpBatchSize;
1263 mCurrentFrame.fbCount = fbBatchSize;
1264 mCurrentFrame.mdpCount = mdpBatchSize;
1265
1266 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1267 __FUNCTION__, mdpBatchSize, fbBatchSize,
1268 mCurrentFrame.dropCount);
1269
1270 if(postHeuristicsHandling(ctx, list)) {
1271 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001272 __FUNCTION__);
1273 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1274 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001275 return true;
1276 }
1277
1278 reset(ctx);
1279 --mdpBatchSize;
1280 ++fbBatchSize;
1281 }
1282
1283 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001284}
1285
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001286bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301287 if(mDpy or isSecurePresent(ctx, mDpy) or
1288 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001289 return false;
1290 }
1291 return true;
1292}
1293
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001294bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1295 hwc_display_contents_1_t* list){
1296 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1297 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001298 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001299 return false;
1300 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001301 if(ctx->listStats[mDpy].secureUI)
1302 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001303 return true;
1304}
1305
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001306bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1307 hwc_display_contents_1_t* list) {
1308 const bool secureOnly = true;
1309 return videoOnlyComp(ctx, list, not secureOnly) or
1310 videoOnlyComp(ctx, list, secureOnly);
1311}
1312
1313bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001314 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001315 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1316 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301317
Saurabh Shahaa236822013-04-24 18:07:26 -07001318 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301319 if(!isSecurePresent(ctx, mDpy)) {
1320 /* Bail out if we are processing only secured video layers
1321 * and we dont have any */
1322 if(secureOnly) {
1323 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1324 return false;
1325 }
1326 /* No Idle fall back for secure video layers and if there is only
1327 * single layer being composed. */
1328 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1329 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1330 return false;
1331 }
1332 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001333
Saurabh Shahaa236822013-04-24 18:07:26 -07001334 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001335 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001336 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001337 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001338
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001339 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1340 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001341 return false;
1342 }
1343
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001344 if(mCurrentFrame.fbCount)
1345 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001346
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001347 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001348 adjustForSourceSplit(ctx, list);
1349 }
1350
1351 if(!postHeuristicsHandling(ctx, list)) {
1352 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301353 if(errno == ENOBUFS) {
1354 ALOGD_IF(isDebug(), "SMP Allocation failed");
1355 //On SMP allocation failure in video only comp add padding round
1356 ctx->isPaddingRound = true;
1357 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001358 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001359 return false;
1360 }
1361
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001362 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1363 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001364 return true;
1365}
1366
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001367/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1368bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1369 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001370 // Fall back to video only composition, if AIV video mode is enabled
1371 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001372 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1373 __FUNCTION__, mDpy);
1374 return false;
1375 }
1376
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001377 // No MDP composition for 3D
1378 if(needs3DComposition(ctx,mDpy))
1379 return false;
1380
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001381 const bool secureOnly = true;
1382 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1383 mdpOnlyLayersComp(ctx, list, secureOnly);
1384
1385}
1386
1387bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1388 hwc_display_contents_1_t* list, bool secureOnly) {
1389
1390 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1391 return false;
1392
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301393 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1394 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1395 /* Bail out if we are processing only secured video/ui layers
1396 * and we dont have any */
1397 if(secureOnly) {
1398 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1399 return false;
1400 }
1401 /* No Idle fall back for secure video/ui layers and if there is only
1402 * single layer being composed. */
1403 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1404 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1405 return false;
1406 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001407 }
1408
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001409 /* Bail out if we dont have any secure RGB layers */
1410 if (!ctx->listStats[mDpy].secureRGBCount) {
1411 reset(ctx);
1412 return false;
1413 }
1414
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001415 mCurrentFrame.reset(numAppLayers);
1416 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1417
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001418 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001419 /* mark secure RGB layers for MDP comp */
1420 updateSecureRGB(ctx, list);
1421
1422 if(mCurrentFrame.mdpCount == 0) {
1423 reset(ctx);
1424 return false;
1425 }
1426
1427 /* find the maximum batch of layers to be marked for framebuffer */
1428 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1429 if(!ret) {
1430 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1431 reset(ctx);
1432 return false;
1433 }
1434
1435 if(sEnableYUVsplit){
1436 adjustForSourceSplit(ctx, list);
1437 }
1438
1439 if(!postHeuristicsHandling(ctx, list)) {
1440 ALOGD_IF(isDebug(), "post heuristic handling failed");
1441 reset(ctx);
1442 return false;
1443 }
1444
1445 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1446 __FUNCTION__);
1447 return true;
1448}
1449
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001450/* Checks for conditions where YUV layers cannot be bypassed */
1451bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001452 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001453 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001454 return false;
1455 }
1456
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001457 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001458 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1459 return false;
1460 }
1461
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001462 if(isSecuring(ctx, layer)) {
1463 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1464 return false;
1465 }
1466
Saurabh Shah4fdde762013-04-30 18:47:33 -07001467 if(!isValidDimension(ctx, layer)) {
1468 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1469 __FUNCTION__);
1470 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001471 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001472
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001473 if(layer->planeAlpha < 0xFF) {
1474 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1475 in video only mode",
1476 __FUNCTION__);
1477 return false;
1478 }
1479
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001480 return true;
1481}
1482
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001483/* Checks for conditions where Secure RGB layers cannot be bypassed */
1484bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1485 if(isSkipLayer(layer)) {
1486 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1487 __FUNCTION__, mDpy);
1488 return false;
1489 }
1490
1491 if(isSecuring(ctx, layer)) {
1492 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1493 return false;
1494 }
1495
1496 if(not isSupportedForMDPComp(ctx, layer)) {
1497 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1498 __FUNCTION__);
1499 return false;
1500 }
1501 return true;
1502}
1503
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301504/* starts at fromIndex and check for each layer to find
1505 * if it it has overlapping with any Updating layer above it in zorder
1506 * till the end of the batch. returns true if it finds any intersection */
1507bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1508 int fromIndex, int toIndex) {
1509 for(int i = fromIndex; i < toIndex; i++) {
1510 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1511 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1512 return false;
1513 }
1514 }
1515 }
1516 return true;
1517}
1518
1519/* Checks if given layer at targetLayerIndex has any
1520 * intersection with all the updating layers in beween
1521 * fromIndex and toIndex. Returns true if it finds intersectiion */
1522bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1523 int fromIndex, int toIndex, int targetLayerIndex) {
1524 for(int i = fromIndex; i <= toIndex; i++) {
1525 if(!mCurrentFrame.isFBComposed[i]) {
1526 if(areLayersIntersecting(&list->hwLayers[i],
1527 &list->hwLayers[targetLayerIndex])) {
1528 return true;
1529 }
1530 }
1531 }
1532 return false;
1533}
1534
1535int MDPComp::getBatch(hwc_display_contents_1_t* list,
1536 int& maxBatchStart, int& maxBatchEnd,
1537 int& maxBatchCount) {
1538 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301539 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001540 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301541 while (i < mCurrentFrame.layerCount) {
1542 int batchCount = 0;
1543 int batchStart = i;
1544 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001545 /* Adjust batch Z order with the dropped layers so far */
1546 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301547 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301548 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301549 while(i < mCurrentFrame.layerCount) {
1550 if(!mCurrentFrame.isFBComposed[i]) {
1551 if(!batchCount) {
1552 i++;
1553 break;
1554 }
1555 updatingLayersAbove++;
1556 i++;
1557 continue;
1558 } else {
1559 if(mCurrentFrame.drop[i]) {
1560 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001561 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301562 continue;
1563 } else if(updatingLayersAbove <= 0) {
1564 batchCount++;
1565 batchEnd = i;
1566 i++;
1567 continue;
1568 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1569
1570 // We have a valid updating layer already. If layer-i not
1571 // have overlapping with all updating layers in between
1572 // batch-start and i, then we can add layer i to batch.
1573 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1574 batchCount++;
1575 batchEnd = i;
1576 i++;
1577 continue;
1578 } else if(canPushBatchToTop(list, batchStart, i)) {
1579 //If All the non-updating layers with in this batch
1580 //does not have intersection with the updating layers
1581 //above in z-order, then we can safely move the batch to
1582 //higher z-order. Increment fbZ as it is moving up.
1583 if( firstZReverseIndex < 0) {
1584 firstZReverseIndex = i;
1585 }
1586 batchCount++;
1587 batchEnd = i;
1588 fbZ += updatingLayersAbove;
1589 i++;
1590 updatingLayersAbove = 0;
1591 continue;
1592 } else {
1593 //both failed.start the loop again from here.
1594 if(firstZReverseIndex >= 0) {
1595 i = firstZReverseIndex;
1596 }
1597 break;
1598 }
1599 }
1600 }
1601 }
1602 if(batchCount > maxBatchCount) {
1603 maxBatchCount = batchCount;
1604 maxBatchStart = batchStart;
1605 maxBatchEnd = batchEnd;
1606 fbZOrder = fbZ;
1607 }
1608 }
1609 return fbZOrder;
1610}
1611
1612bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1613 hwc_display_contents_1_t* list) {
1614 /* Idea is to keep as many non-updating(cached) layers in FB and
1615 * send rest of them through MDP. This is done in 2 steps.
1616 * 1. Find the maximum contiguous batch of non-updating layers.
1617 * 2. See if we can improve this batch size for caching by adding
1618 * opaque layers around the batch, if they don't have
1619 * any overlapping with the updating layers in between.
1620 * NEVER mark an updating layer for caching.
1621 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001622
1623 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001624 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001625 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301626 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001628 /* Nothing is cached. No batching needed */
1629 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001630 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001631 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001632
1633 /* No MDP comp layers, try to use other comp modes */
1634 if(mCurrentFrame.mdpCount == 0) {
1635 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001636 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001637
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301638 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001639
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301640 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001641 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001642 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001643 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301644 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001645 if(!mCurrentFrame.drop[i]){
1646 //If an unsupported layer is being attempted to
1647 //be pulled out we should fail
1648 if(not isSupportedForMDPComp(ctx, layer)) {
1649 return false;
1650 }
1651 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001652 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001653 }
1654 }
1655
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301656 // update the frame data
1657 mCurrentFrame.fbZ = fbZ;
1658 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001659 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001660 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001661
1662 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301663 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001664
1665 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001667
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001668void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001669 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001671 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001673 for(int i = 0; i < numAppLayers; i++) {
1674 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001675 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001676 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001677 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001679 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001680 }
1681 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001682
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001683 frame.fbCount = fbCount;
1684 frame.mdpCount = frame.layerCount - frame.fbCount
1685 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001686
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001687 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1688 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001689}
1690
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001691// drop other non-AIV layers from external display list.
1692void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001693 hwc_display_contents_1_t* list) {
1694 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1695 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001696 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001697 mCurrentFrame.dropCount++;
1698 mCurrentFrame.drop[i] = true;
1699 }
1700 }
1701 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1702 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1703 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1704 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1705 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1706 mCurrentFrame.dropCount);
1707}
1708
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001709void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001710 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001711 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1712 for(int index = 0;index < nYuvCount; index++){
1713 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1714 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1715
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001716 if(mCurrentFrame.drop[nYuvIndex]) {
1717 continue;
1718 }
1719
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001720 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001721 if(!frame.isFBComposed[nYuvIndex]) {
1722 frame.isFBComposed[nYuvIndex] = true;
1723 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001724 }
1725 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001726 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001727 private_handle_t *hnd = (private_handle_t *)layer->handle;
1728 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001729 frame.isFBComposed[nYuvIndex] = false;
1730 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001731 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001732 }
1733 }
1734 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001735
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001736 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1737 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001738}
1739
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001740void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1741 hwc_display_contents_1_t* list) {
1742 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1743 for(int index = 0;index < nSecureRGBCount; index++){
1744 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1745 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1746
1747 if(!isSecureRGBDoable(ctx, layer)) {
1748 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1749 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1750 mCurrentFrame.fbCount++;
1751 }
1752 } else {
1753 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1754 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1755 mCurrentFrame.fbCount--;
1756 }
1757 }
1758 }
1759
1760 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1761 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1762 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1763 mCurrentFrame.fbCount);
1764}
1765
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001766hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1767 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001768 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001769
1770 /* Update only the region of FB needed for composition */
1771 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1772 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1773 hwc_layer_1_t* layer = &list->hwLayers[i];
1774 hwc_rect_t dst = layer->displayFrame;
1775 fbRect = getUnion(fbRect, dst);
1776 }
1777 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001778 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001779 return fbRect;
1780}
1781
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001782bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1783 hwc_display_contents_1_t* list) {
1784
1785 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001786 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001787 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1788 return false;
1789 }
1790
1791 //Limitations checks
1792 if(!hwLimitationsCheck(ctx, list)) {
1793 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1794 return false;
1795 }
1796
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001797 //Configure framebuffer first if applicable
1798 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001799 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001800 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1801 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001802 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1803 __FUNCTION__);
1804 return false;
1805 }
1806 }
1807
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001808 mCurrentFrame.map();
1809
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001810 if(!allocLayerPipes(ctx, list)) {
1811 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001812 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001813 }
1814
1815 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001816 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001817 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001818 int mdpIndex = mCurrentFrame.layerToMDP[index];
1819 hwc_layer_1_t* layer = &list->hwLayers[index];
1820
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301821 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1822 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1823 mdpNextZOrder++;
1824 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001825 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1826 cur_pipe->zOrder = mdpNextZOrder++;
1827
radhakrishnac9a67412013-09-25 17:40:42 +05301828 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301829 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301830 if(configure4k2kYuv(ctx, layer,
1831 mCurrentFrame.mdpToLayer[mdpIndex])
1832 != 0 ){
1833 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1834 for layer %d",__FUNCTION__, index);
1835 return false;
1836 }
1837 else{
1838 mdpNextZOrder++;
1839 }
1840 continue;
1841 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001842 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1843 mdpNextZOrder++;
1844 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001845 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1846 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301847 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001848 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001849 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001850 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001851 }
1852
Saurabh Shaha36be922013-12-16 18:18:39 -08001853 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1854 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1855 ,__FUNCTION__, mDpy);
1856 return false;
1857 }
1858
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001859 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001860 return true;
1861}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001862
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001863bool MDPComp::resourceCheck(hwc_context_t* ctx,
1864 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001865 const bool fbUsed = mCurrentFrame.fbCount;
1866 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1867 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1868 return false;
1869 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001870
1871 //Will benefit cases where a video has non-updating background.
1872 if((mDpy > HWC_DISPLAY_PRIMARY) and
1873 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1874 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1875 return false;
1876 }
1877
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001878 // Init rotCount to number of rotate sessions used by other displays
1879 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1880 // Count the number of rotator sessions required for current display
1881 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1882 if(!mCurrentFrame.isFBComposed[index]) {
1883 hwc_layer_1_t* layer = &list->hwLayers[index];
1884 private_handle_t *hnd = (private_handle_t *)layer->handle;
1885 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1886 rotCount++;
1887 }
1888 }
1889 }
1890 // if number of layers to rotate exceeds max rotator sessions, bail out.
1891 if(rotCount > RotMgr::MAX_ROT_SESS) {
1892 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1893 __FUNCTION__, mDpy);
1894 return false;
1895 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001896 return true;
1897}
1898
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301899bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1900 hwc_display_contents_1_t* list) {
1901
1902 //A-family hw limitation:
1903 //If a layer need alpha scaling, MDP can not support.
1904 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1905 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1906 if(!mCurrentFrame.isFBComposed[i] &&
1907 isAlphaScaled( &list->hwLayers[i])) {
1908 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1909 return false;
1910 }
1911 }
1912 }
1913
1914 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1915 //If multiple layers requires downscaling and also they are overlapping
1916 //fall back to GPU since MDSS can not handle it.
1917 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1918 qdutils::MDPVersion::getInstance().is8x26()) {
1919 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1920 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1921 if(!mCurrentFrame.isFBComposed[i] &&
1922 isDownscaleRequired(botLayer)) {
1923 //if layer-i is marked for MDP and needs downscaling
1924 //check if any MDP layer on top of i & overlaps with layer-i
1925 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1926 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1927 if(!mCurrentFrame.isFBComposed[j] &&
1928 isDownscaleRequired(topLayer)) {
1929 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1930 topLayer->displayFrame);
1931 if(isValidRect(r))
1932 return false;
1933 }
1934 }
1935 }
1936 }
1937 }
1938 return true;
1939}
1940
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001941// Checks only if videos or single layer(RGB) is updating
1942// which is used for setting dynamic fps or perf hint for single
1943// layer video playback
1944bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1945 hwc_display_contents_1_t* list) {
1946 bool support = false;
1947 FrameInfo frame;
1948 frame.reset(mCurrentFrame.layerCount);
1949 memset(&frame.drop, 0, sizeof(frame.drop));
1950 frame.dropCount = 0;
1951 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1952 updateLayerCache(ctx, list, frame);
1953 updateYUV(ctx, list, false /*secure only*/, frame);
1954 // There are only updating YUV layers or there is single RGB
1955 // Layer(Youtube)
1956 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1957 (frame.layerCount == 1)) {
1958 support = true;
1959 }
1960 return support;
1961}
1962
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301963void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1964 //For primary display, set the dynamic refreshrate
1965 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1966 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301967 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1968 MDPVersion& mdpHw = MDPVersion::getInstance();
1969 if(sIdleFallBack) {
1970 //Set minimum panel refresh rate during idle timeout
1971 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001972 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301973 //Set the new fresh rate, if there is only one updating YUV layer
1974 //or there is one single RGB layer with this request
1975 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1976 }
1977 setRefreshRate(ctx, mDpy, refreshRate);
1978 }
1979}
1980
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001981int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001982 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001983 char property[PROPERTY_VALUE_MAX];
1984
Raj Kamal4393eaa2014-06-06 13:45:20 +05301985 if(!ctx || !list) {
1986 ALOGE("%s: Invalid context or list",__FUNCTION__);
1987 mCachedFrame.reset();
1988 return -1;
1989 }
1990
1991 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001992 if(mDpy == HWC_DISPLAY_PRIMARY) {
1993 sSimulationFlags = 0;
1994 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1995 int currentFlags = atoi(property);
1996 if(currentFlags != sSimulationFlags) {
1997 sSimulationFlags = currentFlags;
1998 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1999 sSimulationFlags, sSimulationFlags);
2000 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002001 }
2002 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002003 // reset PTOR
2004 if(!mDpy)
2005 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002006
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302007 //reset old data
2008 mCurrentFrame.reset(numLayers);
2009 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2010 mCurrentFrame.dropCount = 0;
2011
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302012 //Do not cache the information for next draw cycle.
2013 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2014 ALOGI("%s: Unsupported layer count for mdp composition",
2015 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002016 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302017#ifdef DYNAMIC_FPS
2018 setDynRefreshRate(ctx, list);
2019#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002020 return -1;
2021 }
2022
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002023 // Detect the start of animation and fall back to GPU only once to cache
2024 // all the layers in FB and display FB content untill animation completes.
2025 if(ctx->listStats[mDpy].isDisplayAnimating) {
2026 mCurrentFrame.needsRedraw = false;
2027 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2028 mCurrentFrame.needsRedraw = true;
2029 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2030 }
2031 setMDPCompLayerFlags(ctx, list);
2032 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302033#ifdef DYNAMIC_FPS
2034 setDynRefreshRate(ctx, list);
2035#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002036 ret = -1;
2037 return ret;
2038 } else {
2039 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2040 }
2041
Saurabh Shahb39f8152013-08-22 10:21:44 -07002042 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002043 if(isFrameDoable(ctx)) {
2044 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002045 // if AIV Video mode is enabled, drop all non AIV layers from the
2046 // external display list.
2047 if(ctx->listStats[mDpy].mAIVVideoMode) {
2048 dropNonAIVLayers(ctx, list);
2049 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002050
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002051 // if tryFullFrame fails, try to push all video and secure RGB layers
2052 // to MDP for composition.
2053 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002054 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302055 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002056 setMDPCompLayerFlags(ctx, list);
2057 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002058 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002059 reset(ctx);
2060 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2061 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002062 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002063 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2064 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002065 }
2066 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302067 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2068 enablePartialUpdateForMDP3) {
2069 generateROI(ctx, list);
2070 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2071 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2072 }
2073 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002074 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2075 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002076 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002077 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002078
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002079 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002080 ALOGD("GEOMETRY change: %d",
2081 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002082 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002083 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002084 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002085 }
2086
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002087#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302088 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002089#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002090 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002091
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002092 mCachedFrame.cacheAll(list);
2093 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002094 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002095}
2096
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002097bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302098
2099 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302100 int mdpIndex = mCurrentFrame.layerToMDP[index];
2101 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2102 info.pipeInfo = new MdpYUVPipeInfo;
2103 info.rot = NULL;
2104 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302105
2106 pipe_info.lIndex = ovutils::OV_INVALID;
2107 pipe_info.rIndex = ovutils::OV_INVALID;
2108
Saurabh Shahc62f3982014-03-05 14:28:26 -08002109 Overlay::PipeSpecs pipeSpecs;
2110 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2111 pipeSpecs.needsScaling = true;
2112 pipeSpecs.dpy = mDpy;
2113 pipeSpecs.fb = false;
2114
2115 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302116 if(pipe_info.lIndex == ovutils::OV_INVALID){
2117 bRet = false;
2118 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2119 __FUNCTION__);
2120 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002121 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302122 if(pipe_info.rIndex == ovutils::OV_INVALID){
2123 bRet = false;
2124 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2125 __FUNCTION__);
2126 }
2127 return bRet;
2128}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002129
2130int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2131 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002132 if (ctx->mPtorInfo.isActive()) {
2133 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002134 if (fd < 0) {
2135 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002136 }
2137 }
2138 return fd;
2139}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002140//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002141
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002142void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302143 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002144 //If 4k2k Yuv layer split is possible, and if
2145 //fbz is above 4k2k layer, increment fb zorder by 1
2146 //as we split 4k2k layer and increment zorder for right half
2147 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002148 if(!ctx)
2149 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002150 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302151 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2152 index++) {
2153 if(!mCurrentFrame.isFBComposed[index]) {
2154 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2155 mdpNextZOrder++;
2156 }
2157 mdpNextZOrder++;
2158 hwc_layer_1_t* layer = &list->hwLayers[index];
2159 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302160 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302161 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2162 mCurrentFrame.fbZ += 1;
2163 mdpNextZOrder++;
2164 //As we split 4kx2k yuv layer and program to 2 VG pipes
2165 //(if available) increase mdpcount by 1.
2166 mCurrentFrame.mdpCount++;
2167 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002168 }
2169 }
2170 }
radhakrishnac9a67412013-09-25 17:40:42 +05302171}
2172
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002173/*
2174 * Configures pipe(s) for MDP composition
2175 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002176int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002177 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002178 MdpPipeInfoNonSplit& mdp_info =
2179 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302180 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002181 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002182 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002183
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002184 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2185 __FUNCTION__, layer, zOrder, dest);
2186
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002187 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002188 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002189}
2190
Saurabh Shah88e4d272013-09-03 13:31:29 -07002191bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002192 hwc_display_contents_1_t* list) {
2193 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002194
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002195 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002196
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002197 hwc_layer_1_t* layer = &list->hwLayers[index];
2198 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302199 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002200 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302201 continue;
2202 }
2203 }
2204
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002205 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002206 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002207 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002208 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002209 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002210
Saurabh Shahc62f3982014-03-05 14:28:26 -08002211 Overlay::PipeSpecs pipeSpecs;
2212 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2213 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2214 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2215 (qdutils::MDPVersion::getInstance().is8x26() and
2216 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2217 pipeSpecs.dpy = mDpy;
2218 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002219 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002220
Saurabh Shahc62f3982014-03-05 14:28:26 -08002221 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2222
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002223 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002224 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002225 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002226 }
2227 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002228 return true;
2229}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002230
radhakrishnac9a67412013-09-25 17:40:42 +05302231int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2232 PipeLayerPair& PipeLayerPair) {
2233 MdpYUVPipeInfo& mdp_info =
2234 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2235 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302236 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302237 eDest lDest = mdp_info.lIndex;
2238 eDest rDest = mdp_info.rIndex;
2239
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002240 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302241 lDest, rDest, &PipeLayerPair.rot);
2242}
2243
Saurabh Shah88e4d272013-09-03 13:31:29 -07002244bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002245
Raj Kamal4393eaa2014-06-06 13:45:20 +05302246 if(!isEnabled() or !mModeOn) {
2247 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302248 return true;
2249 }
2250
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002251 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002252 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002253 sHandleTimeout = true;
2254 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002255
2256 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002257 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002258
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002259 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2260 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002261 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002262 if(mCurrentFrame.isFBComposed[i]) continue;
2263
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002264 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002265 private_handle_t *hnd = (private_handle_t *)layer->handle;
2266 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002267 if (!(layer->flags & HWC_COLOR_FILL)) {
2268 ALOGE("%s handle null", __FUNCTION__);
2269 return false;
2270 }
2271 // No PLAY for Color layer
2272 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2273 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002274 }
2275
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002276 int mdpIndex = mCurrentFrame.layerToMDP[i];
2277
Raj Kamal389d6e32014-08-04 14:43:24 +05302278 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302279 {
2280 MdpYUVPipeInfo& pipe_info =
2281 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2282 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2283 ovutils::eDest indexL = pipe_info.lIndex;
2284 ovutils::eDest indexR = pipe_info.rIndex;
2285 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302286 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302287 if(rot) {
2288 rot->queueBuffer(fd, offset);
2289 fd = rot->getDstMemId();
2290 offset = rot->getDstOffset();
2291 }
2292 if(indexL != ovutils::OV_INVALID) {
2293 ovutils::eDest destL = (ovutils::eDest)indexL;
2294 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2295 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2296 if (!ov.queueBuffer(fd, offset, destL)) {
2297 ALOGE("%s: queueBuffer failed for display:%d",
2298 __FUNCTION__, mDpy);
2299 return false;
2300 }
2301 }
2302
2303 if(indexR != ovutils::OV_INVALID) {
2304 ovutils::eDest destR = (ovutils::eDest)indexR;
2305 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2306 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2307 if (!ov.queueBuffer(fd, offset, destR)) {
2308 ALOGE("%s: queueBuffer failed for display:%d",
2309 __FUNCTION__, mDpy);
2310 return false;
2311 }
2312 }
2313 }
2314 else{
2315 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002316 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302317 ovutils::eDest dest = pipe_info.index;
2318 if(dest == ovutils::OV_INVALID) {
2319 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002320 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302321 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002322
radhakrishnac9a67412013-09-25 17:40:42 +05302323 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2324 continue;
2325 }
2326
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002327 int fd = hnd->fd;
2328 uint32_t offset = (uint32_t)hnd->offset;
2329 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2330 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002331 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002332 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002333 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002334 }
2335
radhakrishnac9a67412013-09-25 17:40:42 +05302336 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2337 using pipe: %d", __FUNCTION__, layer,
2338 hnd, dest );
2339
radhakrishnac9a67412013-09-25 17:40:42 +05302340 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2341 if(rot) {
2342 if(!rot->queueBuffer(fd, offset))
2343 return false;
2344 fd = rot->getDstMemId();
2345 offset = rot->getDstOffset();
2346 }
2347
2348 if (!ov.queueBuffer(fd, offset, dest)) {
2349 ALOGE("%s: queueBuffer failed for display:%d ",
2350 __FUNCTION__, mDpy);
2351 return false;
2352 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002353 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002354
2355 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002356 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002357 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002358}
2359
Saurabh Shah88e4d272013-09-03 13:31:29 -07002360//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002361
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002362void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302363 hwc_display_contents_1_t* list){
2364 //if 4kx2k yuv layer is totally present in either in left half
2365 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302366 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302367 if(mCurrentFrame.fbZ >= 0) {
2368 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2369 index++) {
2370 if(!mCurrentFrame.isFBComposed[index]) {
2371 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2372 mdpNextZOrder++;
2373 }
2374 mdpNextZOrder++;
2375 hwc_layer_1_t* layer = &list->hwLayers[index];
2376 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002377 if(isYUVSplitNeeded(hnd) ||
2378 (needs3DComposition(ctx,mDpy) &&
2379 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302380 hwc_rect_t dst = layer->displayFrame;
2381 if((dst.left > lSplit) || (dst.right < lSplit)) {
2382 mCurrentFrame.mdpCount += 1;
2383 }
2384 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2385 mCurrentFrame.fbZ += 1;
2386 mdpNextZOrder++;
2387 }
2388 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002389 }
radhakrishnac9a67412013-09-25 17:40:42 +05302390 }
2391}
2392
Saurabh Shah88e4d272013-09-03 13:31:29 -07002393bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002394 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002395
Saurabh Shahc62f3982014-03-05 14:28:26 -08002396 const int lSplit = getLeftSplit(ctx, mDpy);
2397 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002398 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002399 pipe_info.lIndex = ovutils::OV_INVALID;
2400 pipe_info.rIndex = ovutils::OV_INVALID;
2401
Saurabh Shahc62f3982014-03-05 14:28:26 -08002402 Overlay::PipeSpecs pipeSpecs;
2403 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2404 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2405 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2406 pipeSpecs.dpy = mDpy;
2407 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2408 pipeSpecs.fb = false;
2409
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002410 // Acquire pipe only for the updating half
2411 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2412 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2413
2414 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002415 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002416 if(pipe_info.lIndex == ovutils::OV_INVALID)
2417 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002418 }
2419
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002420 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002421 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2422 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002423 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002424 return false;
2425 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002426
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002427 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002428}
2429
Saurabh Shah88e4d272013-09-03 13:31:29 -07002430bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002431 hwc_display_contents_1_t* list) {
2432 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002433
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002434 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002435
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002436 hwc_layer_1_t* layer = &list->hwLayers[index];
2437 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302438 hwc_rect_t dst = layer->displayFrame;
2439 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302440 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302441 if((dst.left > lSplit)||(dst.right < lSplit)){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002442 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302443 continue;
2444 }
2445 }
2446 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002447 //XXX: Check for forced 2D composition
2448 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2449 if(allocSplitVGPipes(ctx,index))
2450 continue;
2451
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002452 int mdpIndex = mCurrentFrame.layerToMDP[index];
2453 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002454 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002455 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002456 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002457
Saurabh Shahc62f3982014-03-05 14:28:26 -08002458 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2459 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2460 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002461 return false;
2462 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002463 }
2464 return true;
2465}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002466
radhakrishnac9a67412013-09-25 17:40:42 +05302467int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2468 PipeLayerPair& PipeLayerPair) {
2469 const int lSplit = getLeftSplit(ctx, mDpy);
2470 hwc_rect_t dst = layer->displayFrame;
2471 if((dst.left > lSplit)||(dst.right < lSplit)){
2472 MdpYUVPipeInfo& mdp_info =
2473 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2474 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302475 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302476 eDest lDest = mdp_info.lIndex;
2477 eDest rDest = mdp_info.rIndex;
2478
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002479 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302480 lDest, rDest, &PipeLayerPair.rot);
2481 }
2482 else{
2483 return configure(ctx, layer, PipeLayerPair);
2484 }
2485}
2486
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002487/*
2488 * Configures pipe(s) for MDP composition
2489 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002490int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002491 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002492 MdpPipeInfoSplit& mdp_info =
2493 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002494 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302495 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002496 eDest lDest = mdp_info.lIndex;
2497 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002498
2499 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002500 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002501
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002502 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002503 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002504}
2505
Saurabh Shah88e4d272013-09-03 13:31:29 -07002506bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002507
Raj Kamal4393eaa2014-06-06 13:45:20 +05302508 if(!isEnabled() or !mModeOn) {
2509 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302510 return true;
2511 }
2512
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002513 // Set the Handle timeout to true for MDP or MIXED composition.
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002514 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount &&
2515 !(needs3DComposition(ctx, HWC_DISPLAY_PRIMARY) ||
2516 needs3DComposition(ctx, HWC_DISPLAY_EXTERNAL))) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002517 sHandleTimeout = true;
2518 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002519
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002520 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002521 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002522
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002523 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2524 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002525 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002526 if(mCurrentFrame.isFBComposed[i]) continue;
2527
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002528 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002529 private_handle_t *hnd = (private_handle_t *)layer->handle;
2530 if(!hnd) {
2531 ALOGE("%s handle null", __FUNCTION__);
2532 return false;
2533 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002534
2535 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2536 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002537 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002538
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002539 int mdpIndex = mCurrentFrame.layerToMDP[i];
2540
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002541 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2542 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302543 {
2544 MdpYUVPipeInfo& pipe_info =
2545 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2546 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2547 ovutils::eDest indexL = pipe_info.lIndex;
2548 ovutils::eDest indexR = pipe_info.rIndex;
2549 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302550 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302551 if(rot) {
2552 rot->queueBuffer(fd, offset);
2553 fd = rot->getDstMemId();
2554 offset = rot->getDstOffset();
2555 }
2556 if(indexL != ovutils::OV_INVALID) {
2557 ovutils::eDest destL = (ovutils::eDest)indexL;
2558 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2559 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2560 if (!ov.queueBuffer(fd, offset, destL)) {
2561 ALOGE("%s: queueBuffer failed for display:%d",
2562 __FUNCTION__, mDpy);
2563 return false;
2564 }
2565 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002566
radhakrishnac9a67412013-09-25 17:40:42 +05302567 if(indexR != ovutils::OV_INVALID) {
2568 ovutils::eDest destR = (ovutils::eDest)indexR;
2569 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2570 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2571 if (!ov.queueBuffer(fd, offset, destR)) {
2572 ALOGE("%s: queueBuffer failed for display:%d",
2573 __FUNCTION__, mDpy);
2574 return false;
2575 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002576 }
2577 }
radhakrishnac9a67412013-09-25 17:40:42 +05302578 else{
2579 MdpPipeInfoSplit& pipe_info =
2580 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2581 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002582
radhakrishnac9a67412013-09-25 17:40:42 +05302583 ovutils::eDest indexL = pipe_info.lIndex;
2584 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002585
radhakrishnac9a67412013-09-25 17:40:42 +05302586 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002587 uint32_t offset = (uint32_t)hnd->offset;
2588 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2589 if (!mDpy && (index != -1)) {
2590 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2591 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002592 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002593 }
radhakrishnac9a67412013-09-25 17:40:42 +05302594
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002595 if(ctx->mAD->draw(ctx, fd, offset)) {
2596 fd = ctx->mAD->getDstFd();
2597 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002598 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002599
radhakrishnac9a67412013-09-25 17:40:42 +05302600 if(rot) {
2601 rot->queueBuffer(fd, offset);
2602 fd = rot->getDstMemId();
2603 offset = rot->getDstOffset();
2604 }
2605
2606 //************* play left mixer **********
2607 if(indexL != ovutils::OV_INVALID) {
2608 ovutils::eDest destL = (ovutils::eDest)indexL;
2609 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2610 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2611 if (!ov.queueBuffer(fd, offset, destL)) {
2612 ALOGE("%s: queueBuffer failed for left mixer",
2613 __FUNCTION__);
2614 return false;
2615 }
2616 }
2617
2618 //************* play right mixer **********
2619 if(indexR != ovutils::OV_INVALID) {
2620 ovutils::eDest destR = (ovutils::eDest)indexR;
2621 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2622 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2623 if (!ov.queueBuffer(fd, offset, destR)) {
2624 ALOGE("%s: queueBuffer failed for right mixer",
2625 __FUNCTION__);
2626 return false;
2627 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002628 }
2629 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002630
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002631 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2632 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002633
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002634 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002635}
Saurabh Shahab47c692014-02-12 18:45:57 -08002636
2637//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002638
2639bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2640 hwc_display_contents_1_t* list) {
2641 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2642 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2643
2644 for(int i = numAppLayers - 1; i >= 0; i--) {
2645 if(!isValidRect(visibleRect)) {
2646 mCurrentFrame.drop[i] = true;
2647 mCurrentFrame.dropCount++;
2648 continue;
2649 }
2650
2651 const hwc_layer_1_t* layer = &list->hwLayers[i];
2652 hwc_rect_t dstRect = layer->displayFrame;
2653 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2654
2655 if(!isValidRect(res)) {
2656 mCurrentFrame.drop[i] = true;
2657 mCurrentFrame.dropCount++;
2658 } else {
2659 /* Reset frame ROI when any layer which needs scaling also needs ROI
2660 * cropping */
2661 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2662 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2663 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2664 mCurrentFrame.dropCount = 0;
2665 return false;
2666 }
2667
2668 /* deduct any opaque region from visibleRect */
2669 if (layer->blending == HWC_BLENDING_NONE &&
2670 layer->planeAlpha == 0xFF)
2671 visibleRect = deductRect(visibleRect, res);
2672 }
2673 }
2674 return true;
2675}
2676
2677/*
2678 * HW Limitation: ping pong split can always split the ping pong output
2679 * equally across two DSI's. So the ROI programmed should be of equal width
2680 * for both the halves
2681 */
2682void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2683 hwc_display_contents_1_t* list) {
2684 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2685
2686
2687 if(!canPartialUpdate(ctx, list))
2688 return;
2689
2690 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2691 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2692 (int)ctx->dpyAttr[mDpy].yres};
2693
2694 for(int index = 0; index < numAppLayers; index++ ) {
2695 hwc_layer_1_t* layer = &list->hwLayers[index];
2696
2697 // If we have a RGB layer which needs rotation, no partial update
2698 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2699 return;
2700
2701 if ((mCachedFrame.hnd[index] != layer->handle) ||
2702 isYuvBuffer((private_handle_t *)layer->handle)) {
2703 hwc_rect_t dst = layer->displayFrame;
2704 hwc_rect_t updatingRect = dst;
2705
2706#ifdef QCOM_BSP
2707 if(!needsScaling(layer) && !layer->transform)
2708 {
2709 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2710 int x_off = dst.left - src.left;
2711 int y_off = dst.top - src.top;
2712 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2713 }
2714#endif
2715
2716 roi = getUnion(roi, updatingRect);
2717 }
2718 }
2719
2720 /* No layer is updating. Still SF wants a refresh.*/
2721 if(!isValidRect(roi))
2722 return;
2723
2724 roi = expandROIFromMidPoint(roi, fullFrame);
2725
2726 hwc_rect lFrame = fullFrame;
2727 lFrame.right /= 2;
2728 hwc_rect lRoi = getIntersection(roi, lFrame);
2729
2730 // Align ROI coordinates to panel restrictions
2731 lRoi = getSanitizeROI(lRoi, lFrame);
2732
2733 hwc_rect rFrame = fullFrame;
2734 rFrame.left = lFrame.right;
2735 hwc_rect rRoi = getIntersection(roi, rFrame);
2736
2737 // Align ROI coordinates to panel restrictions
2738 rRoi = getSanitizeROI(rRoi, rFrame);
2739
2740 roi = getUnion(lRoi, rRoi);
2741
2742 ctx->listStats[mDpy].lRoi = roi;
2743 if(!validateAndApplyROI(ctx, list))
2744 resetROI(ctx, mDpy);
2745
2746 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2747 __FUNCTION__,
2748 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2749 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2750 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2751 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2752}
2753
Saurabh Shahab47c692014-02-12 18:45:57 -08002754bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002755 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002756 private_handle_t *hnd = (private_handle_t *)layer->handle;
2757 hwc_rect_t dst = layer->displayFrame;
2758 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2759 pipe_info.lIndex = ovutils::OV_INVALID;
2760 pipe_info.rIndex = ovutils::OV_INVALID;
2761
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002762 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2763 trimAgainstROI(ctx,crop, dst);
2764
Saurabh Shahab47c692014-02-12 18:45:57 -08002765 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2766 //should have a higher priority than the right one. Pipe priorities are
2767 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002768
Saurabh Shahc62f3982014-03-05 14:28:26 -08002769 Overlay::PipeSpecs pipeSpecs;
2770 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2771 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2772 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2773 pipeSpecs.dpy = mDpy;
2774 pipeSpecs.fb = false;
2775
Saurabh Shahab47c692014-02-12 18:45:57 -08002776 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002777 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002778 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002779 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002780 }
2781
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002782 /* Use 2 pipes IF
2783 a) Layer's crop width is > 2048 or
2784 b) Layer's dest width > 2048 or
2785 c) On primary, driver has indicated with caps to split always. This is
2786 based on an empirically derived value of panel height. Applied only
2787 if the layer's width is > mixer's width
2788 */
2789
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302790 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002791 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302792 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002793 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2794 const uint32_t dstWidth = dst.right - dst.left;
2795 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002796 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002797 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002798 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002799 crop.bottom - crop.top;
2800 //Approximation to actual clock, ignoring the common factors in pipe and
2801 //mixer cases like line_time
2802 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2803 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002804
Saurabh Shah05f4e222015-02-05 14:36:22 -08002805 const uint32_t downscale = getRotDownscale(ctx, layer);
2806 if(downscale) {
2807 cropWidth /= downscale;
2808 cropHeight /= downscale;
2809 }
2810
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002811 if(dstWidth > mdpHw.getMaxPipeWidth() or
2812 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002813 (primarySplitAlways and
2814 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002815 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002816 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002817 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002818 }
2819
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002820 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2821 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002822 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002823 }
2824 }
2825
2826 return true;
2827}
2828
Saurabh Shahab47c692014-02-12 18:45:57 -08002829int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2830 PipeLayerPair& PipeLayerPair) {
2831 private_handle_t *hnd = (private_handle_t *)layer->handle;
2832 if(!hnd) {
2833 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2834 return -1;
2835 }
2836 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2837 MdpPipeInfoSplit& mdp_info =
2838 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2839 Rotator **rot = &PipeLayerPair.rot;
2840 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002841 eDest lDest = mdp_info.lIndex;
2842 eDest rDest = mdp_info.rIndex;
2843 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2844 hwc_rect_t dst = layer->displayFrame;
2845 int transform = layer->transform;
2846 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002847 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002848 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002849 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002850 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08002851
2852 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2853 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2854
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002855 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2856 /* MDP driver crops layer coordinates against ROI in Non-Split
2857 * and Split MDP comp. But HWC needs to crop them for source split.
2858 * Reason: 1) Source split is efficient only when the final effective
2859 * load is distributed evenly across mixers.
2860 * 2) We have to know the effective width of the layer that
2861 * the ROI needs to find the no. of pipes the layer needs.
2862 */
2863 trimAgainstROI(ctx, crop, dst);
2864 }
2865
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002866 if(needs3DComposition(ctx, mDpy) &&
2867 get3DFormat(hnd) != HAL_NO_3D){
2868 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
2869 rDest, &PipeLayerPair.rot);
2870 }
2871
Saurabh Shahab47c692014-02-12 18:45:57 -08002872 // Handle R/B swap
2873 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2874 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2875 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2876 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2877 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2878 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002879 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002880 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2881 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002882 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002883 /* Calculate the external display position based on MDP downscale,
2884 ActionSafe, and extorientation features. */
2885 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002886
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002887 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002888 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002889
2890 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2891 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002892 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002893 }
2894
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002895 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002896 (*rot) = ctx->mRotMgr->getNext();
2897 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002898 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002899 //If the video is using a single pipe, enable BWC
2900 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002901 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2902 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002903 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002904 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002905 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002906 ALOGE("%s: configRotator failed!", __FUNCTION__);
2907 return -1;
2908 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002909 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002910 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002911 }
2912
2913 //If 2 pipes being used, divide layer into half, crop and dst
2914 hwc_rect_t cropL = crop;
2915 hwc_rect_t cropR = crop;
2916 hwc_rect_t dstL = dst;
2917 hwc_rect_t dstR = dst;
2918 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2919 cropL.right = (crop.right + crop.left) / 2;
2920 cropR.left = cropL.right;
2921 sanitizeSourceCrop(cropL, cropR, hnd);
2922
Saurabh Shahb729b192014-08-15 18:04:24 -07002923 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002924 //Swap crops on H flip since 2 pipes are being used
2925 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2926 hwc_rect_t tmp = cropL;
2927 cropL = cropR;
2928 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002929 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002930 }
2931
Saurabh Shahb729b192014-08-15 18:04:24 -07002932 //cropSwap trick: If the src and dst widths are both odd, let us say
2933 //2507, then splitting both into half would cause left width to be 1253
2934 //and right 1254. If crop is swapped because of H flip, this will cause
2935 //left crop width to be 1254, whereas left dst width remains 1253, thus
2936 //inducing a scaling that is unaccounted for. To overcome that we add 1
2937 //to the dst width if there is a cropSwap. So if the original width was
2938 //2507, the left dst width will be 1254. Even if the original width was
2939 //even for ex: 2508, the left dst width will still remain 1254.
2940 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002941 dstR.left = dstL.right;
2942 }
2943
2944 //For the mdp, since either we are pre-rotating or MDP does flips
2945 orient = OVERLAY_TRANSFORM_0;
2946 transform = 0;
2947
2948 //configure left pipe
2949 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002950 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002951 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2952 (ovutils::eBlending) getBlending(layer->blending));
2953
2954 if(configMdp(ctx->mOverlay, pargL, orient,
2955 cropL, dstL, metadata, lDest) < 0) {
2956 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2957 return -1;
2958 }
2959 }
2960
2961 //configure right pipe
2962 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002963 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002964 static_cast<eRotFlags>(rotFlags),
2965 layer->planeAlpha,
2966 (ovutils::eBlending) getBlending(layer->blending));
2967 if(configMdp(ctx->mOverlay, pargR, orient,
2968 cropR, dstR, metadata, rDest) < 0) {
2969 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2970 return -1;
2971 }
2972 }
2973
2974 return 0;
2975}
2976
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002977bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2978 Locker::Autolock _l(ctx->mDrawLock);
2979 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2980 char path[MAX_SYSFS_FILE_PATH];
2981 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2982 int fd = open(path, O_RDONLY);
2983 if(fd < 0) {
2984 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2985 return -1;
2986 }
2987 char value[4];
2988 ssize_t size_read = read(fd, value, sizeof(value)-1);
2989 if(size_read <= 0) {
2990 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2991 close(fd);
2992 return -1;
2993 }
2994 close(fd);
2995 value[size_read] = '\0';
2996 return atoi(value);
2997}
2998
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002999int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3000 Locker::Autolock _l(ctx->mDrawLock);
3001 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3002 char path[MAX_SYSFS_FILE_PATH];
3003 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3004 int fd = open(path, O_WRONLY);
3005 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003006 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003007 return -1;
3008 }
3009 char value[4];
3010 snprintf(value, sizeof(value), "%d", (int)enable);
3011 ssize_t ret = write(fd, value, strlen(value));
3012 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003013 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003014 close(fd);
3015 return -1;
3016 }
3017 close(fd);
3018 sIsPartialUpdateActive = enable;
3019 return 0;
3020}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003021
3022bool MDPComp::loadPerfLib() {
3023 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3024 bool success = false;
3025 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3026 ALOGE("vendor library not set in ro.vendor.extension_library");
3027 return false;
3028 }
3029
3030 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3031 if(sLibPerfHint) {
3032 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3033 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3034 if (!sPerfLockAcquire || !sPerfLockRelease) {
3035 ALOGE("Failed to load symbols for perfLock");
3036 dlclose(sLibPerfHint);
3037 sLibPerfHint = NULL;
3038 return false;
3039 }
3040 success = true;
3041 ALOGI("Successfully Loaded perf hint API's");
3042 } else {
3043 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3044 }
3045 return success;
3046}
3047
3048void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3049 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3050 return;
3051 }
3052 static int count = sPerfHintWindow;
3053 static int perflockFlag = 0;
3054
3055 /* Send hint to mpctl when single layer is updated
3056 * for a successful number of windows. Hint release
3057 * happens immediately upon multiple layer update.
3058 */
3059 if (onlyVideosUpdating(ctx, list)) {
3060 if(count) {
3061 count--;
3062 }
3063 } else {
3064 if (perflockFlag) {
3065 perflockFlag = 0;
3066 sPerfLockRelease(sPerfLockHandle);
3067 }
3068 count = sPerfHintWindow;
3069 }
3070 if (count == 0 && !perflockFlag) {
3071 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3072 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3073 &perfHint, sizeof(perfHint)/sizeof(int));
3074 if(sPerfLockHandle < 0) {
3075 ALOGE("Perf Lock Acquire Failed");
3076 } else {
3077 perflockFlag = 1;
3078 }
3079 }
3080}
3081
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003082}; //namespace
3083