blob: f3cd5f79197d64e14b41c372ea6a0bf98b18b93e [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080022#include <dlfcn.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070023#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070030#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080031
Saurabh Shah85234ec2013-04-12 17:09:00 -070032using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070033using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080034using namespace overlay::utils;
35namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037namespace qhwc {
38
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080039//==============MDPComp========================================================
40
Saurabh Shah59562ff2014-09-30 16:13:12 -070041IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080043bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070044bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050045bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070046bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070047int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070048int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053049bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070050bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080051int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053052bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070053bool MDPComp::sIsPartialUpdateActive = true;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080054void *MDPComp::sLibPerfHint = NULL;
55int MDPComp::sPerfLockHandle = 0;
56int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
57int (*MDPComp::sPerfLockRelease)(int value) = NULL;
58int MDPComp::sPerfHintWindow = -1;
59
Saurabh Shah88e4d272013-09-03 13:31:29 -070060MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070061 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
62 sSrcSplitEnabled = true;
63 return new MDPCompSrcSplit(dpy);
64 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070065 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080066 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070067 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080068}
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070MDPComp::MDPComp(int dpy):mDpy(dpy){};
71
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070072void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080073{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070074 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
75 return;
76
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080077 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070078 (mDpy == 0) ? "\"PRIMARY\"" :
79 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070080 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
81 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080082 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
83 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
84 (mCurrentFrame.needsRedraw? "YES" : "NO"),
85 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070086 if(isDisplaySplit(ctx, mDpy)) {
87 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
88 "Right: [%d, %d, %d, %d] \n",
89 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
90 ctx->listStats[mDpy].lRoi.right,
91 ctx->listStats[mDpy].lRoi.bottom,
92 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
93 ctx->listStats[mDpy].rRoi.right,
94 ctx->listStats[mDpy].rRoi.bottom);
95 } else {
96 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
97 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
98 ctx->listStats[mDpy].lRoi.right,
99 ctx->listStats[mDpy].lRoi.bottom);
100 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 dumpsys_log(buf," --------------------------------------------- \n");
102 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
103 dumpsys_log(buf," --------------------------------------------- \n");
104 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
105 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
106 index,
107 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700108 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800109 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700110 (mCurrentFrame.drop[index] ? "DROP" :
111 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800112 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
113 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
114 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115}
116
117bool MDPComp::init(hwc_context_t *ctx) {
118
119 if(!ctx) {
120 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
121 return false;
122 }
123
Saurabh Shah59562ff2014-09-30 16:13:12 -0700124 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800125
126 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530127 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
128 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800131 sEnabled = true;
132 }
133
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700134 sEnableMixedMode = true;
135 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
136 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
137 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
138 sEnableMixedMode = false;
139 }
140
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700141 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
142
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800143 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700144 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700145 int val = atoi(property);
146 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700147 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800148 }
149
Saurabh Shahacec8e42014-11-25 11:07:04 -0800150 /* Maximum layers allowed to use MDP on secondary panels. If property
151 * doesn't exist, default to 1. Using the property it can be set to 0 or
152 * more.
153 */
154 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
155 int val = atoi(property);
156 sMaxSecLayers = (val >= 0) ? val : 1;
157 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
158 }
159
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700161 sIdleInvalidator = IdleInvalidator::getInstance();
162 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
163 delete sIdleInvalidator;
164 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400165 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800166 }
radhakrishnac9a67412013-09-25 17:40:42 +0530167
Saurabh Shah7c727642014-06-02 15:47:14 -0700168 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700169 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700170 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
171 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
172 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530173 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530174 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700175
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530176 bool defaultPTOR = false;
177 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
178 //8x16 and 8x39 targets by default
179 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
180 (qdutils::MDPVersion::getInstance().is8x16() ||
181 qdutils::MDPVersion::getInstance().is8x39())) {
182 defaultPTOR = true;
183 }
184
185 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
186 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700187 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
188 HWC_DISPLAY_PRIMARY);
189 }
190
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530191 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
192 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
193 enablePartialUpdateForMDP3 = true;
194 }
195
196 if(!enablePartialUpdateForMDP3 &&
197 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
198 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
199 enablePartialUpdateForMDP3 = true;
200 }
201
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800202 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
203
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800204 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
205 int val = atoi(property);
206 if(val > 0 && loadPerfLib()) {
207 sPerfHintWindow = val;
208 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
209 }
210 }
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212 return true;
213}
214
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800215void MDPComp::reset(hwc_context_t *ctx) {
216 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700217 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800218 ctx->mOverlay->clear(mDpy);
219 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700220}
221
Raj Kamal4393eaa2014-06-06 13:45:20 +0530222void MDPComp::reset() {
223 sHandleTimeout = false;
224 mModeOn = false;
225}
226
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227void MDPComp::timeout_handler(void *udata) {
228 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
229
230 if(!ctx) {
231 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
232 return;
233 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530234
235 ctx->mDrawLock.lock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800236 // Handle timeout event only if the previous composition is MDP or MIXED.
237 if(!sHandleTimeout) {
238 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530239 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800240 return;
241 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700242 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700243 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530244 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700245 return;
246 }
247 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530248 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700249 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700250 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700251}
252
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700253void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
254 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800255 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700256 if(value > maxSupported) {
257 ALOGW("%s: Input exceeds max value supported. Setting to"
258 "max value: %d", __FUNCTION__, maxSupported);
259 }
260 sMaxPipesPerMixer = min(value, maxSupported);
261}
262
Saurabh Shah59562ff2014-09-30 16:13:12 -0700263void MDPComp::setIdleTimeout(const uint32_t& timeout) {
264 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
265
266 if(sIdleInvalidator) {
267 if(timeout <= ONE_REFRESH_PERIOD_MS) {
268 //If the specified timeout is < 1 draw cycle worth, "virtually"
269 //disable idle timeout. The ideal way for clients to disable
270 //timeout is to set it to 0
271 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
272 ALOGI("Disabled idle timeout");
273 return;
274 }
275 sIdleInvalidator->setIdleTimeout(timeout);
276 ALOGI("Idle timeout set to %u", timeout);
277 } else {
278 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
279 }
280}
281
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800282void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283 hwc_display_contents_1_t* list) {
284 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800285
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800287 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800288 if(!mCurrentFrame.isFBComposed[index]) {
289 layerProp[index].mFlags |= HWC_MDPCOMP;
290 layer->compositionType = HWC_OVERLAY;
291 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800292 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700293 /* Drop the layer when its already present in FB OR when it lies
294 * outside frame's ROI */
295 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700297 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800298 }
299 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700300}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500301
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800302void MDPComp::setRedraw(hwc_context_t *ctx,
303 hwc_display_contents_1_t* list) {
304 mCurrentFrame.needsRedraw = false;
305 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
306 (list->flags & HWC_GEOMETRY_CHANGED) ||
307 isSkipPresent(ctx, mDpy)) {
308 mCurrentFrame.needsRedraw = true;
309 }
310}
311
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800312MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700313 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700314 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316
Saurabh Shahaa236822013-04-24 18:07:26 -0700317void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700318 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800319 if(mdpToLayer[i].pipeInfo) {
320 delete mdpToLayer[i].pipeInfo;
321 mdpToLayer[i].pipeInfo = NULL;
322 //We dont own the rotator
323 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800324 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800325 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800326
327 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
328 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700329 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330
Saurabh Shahaa236822013-04-24 18:07:26 -0700331 layerCount = numLayers;
332 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800333 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700334 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800335 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336}
337
Saurabh Shahaa236822013-04-24 18:07:26 -0700338void MDPComp::FrameInfo::map() {
339 // populate layer and MDP maps
340 int mdpIdx = 0;
341 for(int idx = 0; idx < layerCount; idx++) {
342 if(!isFBComposed[idx]) {
343 mdpToLayer[mdpIdx].listIndex = idx;
344 layerToMDP[idx] = mdpIdx++;
345 }
346 }
347}
348
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800349MDPComp::LayerCache::LayerCache() {
350 reset();
351}
352
353void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700354 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530355 memset(&isFBComposed, true, sizeof(isFBComposed));
356 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700358}
359
360void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530361 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700362 for(int i = 0; i < numAppLayers; i++) {
363 hnd[i] = list->hwLayers[i].handle;
364 }
365}
366
367void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700368 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530369 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
370 memcpy(&drop, &curFrame.drop, sizeof(drop));
371}
372
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800373bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
374 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530375 if(layerCount != curFrame.layerCount)
376 return false;
377 for(int i = 0; i < curFrame.layerCount; i++) {
378 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
379 (curFrame.drop[i] != drop[i])) {
380 return false;
381 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800382 if(curFrame.isFBComposed[i] &&
383 (hnd[i] != list->hwLayers[i].handle)){
384 return false;
385 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530386 }
387 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800388}
389
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700390bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
391 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800392 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700393 (not isValidDimension(ctx,layer))
394 //More conditions here, SKIP, sRGB+Blend etc
395 ) {
396 return false;
397 }
398 return true;
399}
400
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530401bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800402 private_handle_t *hnd = (private_handle_t *)layer->handle;
403
404 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700405 if (layer->flags & HWC_COLOR_FILL) {
406 // Color layer
407 return true;
408 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700409 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return false;
411 }
412
Naseer Ahmede850a802013-09-06 13:12:52 -0400413 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400414 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400415 return false;
416
Saurabh Shah62e1d732013-09-17 10:44:05 -0700417 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700418 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700419 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700420 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
421 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700422 int dst_w = dst.right - dst.left;
423 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800424 float w_scale = ((float)crop_w / (float)dst_w);
425 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530426 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800428 /* Workaround for MDP HW limitation in DSI command mode panels where
429 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
430 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530431 * There also is a HW limilation in MDP, minimum block size is 2x2
432 * Fallback to GPU if height is less than 2.
433 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700434 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800435 return false;
436
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800437 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530438 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800439 const float w_dscale = w_scale;
440 const float h_dscale = h_scale;
441
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800442 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700443
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530444 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700445 /* On targets that doesnt support Decimation (eg.,8x26)
446 * maximum downscale support is overlay pipe downscale.
447 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800448 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530449 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700450 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800451 return false;
452 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700453 // Decimation on macrotile format layers is not supported.
454 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530455 /* Bail out if
456 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700457 * 2. exceeds maximum downscale limit
458 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800459 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530460 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700461 w_dscale > maxMDPDownscale ||
462 h_dscale > maxMDPDownscale) {
463 return false;
464 }
465 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800466 return false;
467 }
468 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700469 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700470 return false;
471 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700472 }
473
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800474 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530475 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800476 const float w_uscale = 1.0f / w_scale;
477 const float h_uscale = 1.0f / h_scale;
478
479 if(w_uscale > upscale || h_uscale > upscale)
480 return false;
481 }
482
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800483 return true;
484}
485
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800486bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700487 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800488
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800489 if(!isEnabled()) {
490 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700491 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530492 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530493 qdutils::MDPVersion::getInstance().is8x16() ||
494 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800495 ctx->mVideoTransFlag &&
496 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700497 //1 Padding round to shift pipes across mixers
498 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
499 __FUNCTION__);
500 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700501 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
502 /* TODO: freeing up all the resources only for the targets having total
503 number of pipes < 8. Need to analyze number of VIG pipes used
504 for primary in previous draw cycle and accordingly decide
505 whether to fall back to full GPU comp or video only comp
506 */
507 if(isSecondaryConfiguring(ctx)) {
508 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
509 __FUNCTION__);
510 ret = false;
511 } else if(ctx->isPaddingRound) {
512 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
513 __FUNCTION__,mDpy);
514 ret = false;
515 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800516 } else if (ctx->isDMAStateChanging) {
517 // Bail out if a padding round has been invoked in order to switch DMA
518 // state to block mode. We need this to cater for the case when a layer
519 // requires rotation in the current frame.
520 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
521 __FUNCTION__);
522 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700523 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800524
Saurabh Shahaa236822013-04-24 18:07:26 -0700525 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800526}
527
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800528void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
529 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800530 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800531 dst = getIntersection(dst, roi);
532 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800533}
534
535/* 1) Identify layers that are not visible or lying outside the updating ROI and
536 * drop them from composition.
537 * 2) If we have a scaling layer which needs cropping against generated
538 * ROI, reset ROI to full resolution. */
539bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
540 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700541 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800542 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800543
544 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800545 if(!isValidRect(visibleRect)) {
546 mCurrentFrame.drop[i] = true;
547 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800548 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800549 }
550
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700551 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700552 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800553 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700554
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700555 if(!isValidRect(res)) {
556 mCurrentFrame.drop[i] = true;
557 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800558 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700559 /* Reset frame ROI when any layer which needs scaling also needs ROI
560 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800561 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800562 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700563 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
564 mCurrentFrame.dropCount = 0;
565 return false;
566 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800567
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800568 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530569 if (layer->blending == HWC_BLENDING_NONE &&
570 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800571 visibleRect = deductRect(visibleRect, res);
572 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700573 }
574 return true;
575}
576
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
578 * are updating. If DirtyRegion is applicable, calculate it by accounting all
579 * the changing layer's dirtyRegion. */
580void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
581 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700582 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800583 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700584 return;
585
586 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800587 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
588 (int)ctx->dpyAttr[mDpy].yres};
589
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700590 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800591 hwc_layer_1_t* layer = &list->hwLayers[index];
592 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800593 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700594 hwc_rect_t dst = layer->displayFrame;
595 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800596
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800597#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800598 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700599 {
600 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
601 int x_off = dst.left - src.left;
602 int y_off = dst.top - src.top;
603 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
604 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800605#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800606
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800607 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700608 }
609 }
610
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800611 /* No layer is updating. Still SF wants a refresh.*/
612 if(!isValidRect(roi))
613 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800614
615 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800616 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800617
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800618 ctx->listStats[mDpy].lRoi = roi;
619 if(!validateAndApplyROI(ctx, list))
620 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700621
622 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800623 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
624 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
625}
626
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800627void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
628 hwc_rect &dst) {
629 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
630 ctx->listStats[mDpy].rRoi);
631 hwc_rect tmpDst = getIntersection(dst, roi);
632 if(!isSameRect(dst, tmpDst)) {
633 crop.left = crop.left + (tmpDst.left - dst.left);
634 crop.top = crop.top + (tmpDst.top - dst.top);
635 crop.right = crop.left + (tmpDst.right - tmpDst.left);
636 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
637 dst = tmpDst;
638 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800639}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800640
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800641/* 1) Identify layers that are not visible or lying outside BOTH the updating
642 * ROI's and drop them from composition. If a layer is spanning across both
643 * the halves of the screen but needed by only ROI, the non-contributing
644 * half will not be programmed for MDP.
645 * 2) If we have a scaling layer which needs cropping against generated
646 * ROI, reset ROI to full resolution. */
647bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
648 hwc_display_contents_1_t* list) {
649
650 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
651
652 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
653 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
654
655 for(int i = numAppLayers - 1; i >= 0; i--){
656 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
657 {
658 mCurrentFrame.drop[i] = true;
659 mCurrentFrame.dropCount++;
660 continue;
661 }
662
663 const hwc_layer_1_t* layer = &list->hwLayers[i];
664 hwc_rect_t dstRect = layer->displayFrame;
665
666 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
667 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
668 hwc_rect_t res = getUnion(l_res, r_res);
669
670 if(!isValidRect(l_res) && !isValidRect(r_res)) {
671 mCurrentFrame.drop[i] = true;
672 mCurrentFrame.dropCount++;
673 } else {
674 /* Reset frame ROI when any layer which needs scaling also needs ROI
675 * cropping */
676 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
677 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
678 mCurrentFrame.dropCount = 0;
679 return false;
680 }
681
radhakrishna4efbdd62014-11-03 13:19:27 +0530682 if (layer->blending == HWC_BLENDING_NONE &&
683 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800684 visibleRectL = deductRect(visibleRectL, l_res);
685 visibleRectR = deductRect(visibleRectR, r_res);
686 }
687 }
688 }
689 return true;
690}
691/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
692 * are updating. If DirtyRegion is applicable, calculate it by accounting all
693 * the changing layer's dirtyRegion. */
694void MDPCompSplit::generateROI(hwc_context_t *ctx,
695 hwc_display_contents_1_t* list) {
696 if(!canPartialUpdate(ctx, list))
697 return;
698
699 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
700 int lSplit = getLeftSplit(ctx, mDpy);
701
702 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
703 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
704
705 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
706 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
707
708 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
709 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
710
711 for(int index = 0; index < numAppLayers; index++ ) {
712 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800713 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800714 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800715 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700716 hwc_rect_t dst = layer->displayFrame;
717 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800718
719#ifdef QCOM_BSP
720 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700721 {
722 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
723 int x_off = dst.left - src.left;
724 int y_off = dst.top - src.top;
725 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
726 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800727#endif
728
729 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
730 if(isValidRect(l_dst))
731 l_roi = getUnion(l_roi, l_dst);
732
733 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
734 if(isValidRect(r_dst))
735 r_roi = getUnion(r_roi, r_dst);
736 }
737 }
738
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700739 /* For panels that cannot accept commands in both the interfaces, we cannot
740 * send two ROI's (for each half). We merge them into single ROI and split
741 * them across lSplit for MDP mixer use. The ROI's will be merged again
742 * finally before udpating the panel in the driver. */
743 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
744 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
745 l_roi = getIntersection(temp_roi, l_frame);
746 r_roi = getIntersection(temp_roi, r_frame);
747 }
748
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800749 /* No layer is updating. Still SF wants a refresh. */
750 if(!isValidRect(l_roi) && !isValidRect(r_roi))
751 return;
752
753 l_roi = getSanitizeROI(l_roi, l_frame);
754 r_roi = getSanitizeROI(r_roi, r_frame);
755
756 ctx->listStats[mDpy].lRoi = l_roi;
757 ctx->listStats[mDpy].rRoi = r_roi;
758
759 if(!validateAndApplyROI(ctx, list))
760 resetROI(ctx, mDpy);
761
762 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
763 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
764 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
765 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
766 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
767 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700768}
769
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800770/* Checks for conditions where all the layers marked for MDP comp cannot be
771 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800772bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800773 hwc_display_contents_1_t* list){
774
Saurabh Shahaa236822013-04-24 18:07:26 -0700775 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800776
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700777 // Fall back to video only composition, if AIV video mode is enabled
778 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700779 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
780 __FUNCTION__, mDpy);
781 return false;
782 }
783
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530784 /* No Idle fall back if secure display or secure RGB layers are present
785 * or if there is only a single layer being composed */
786 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
787 !ctx->listStats[mDpy].secureRGBCount &&
788 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700789 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
790 return false;
791 }
792
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800793 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700794 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
795 __FUNCTION__,
796 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800797 return false;
798 }
799
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700800 // if secondary is configuring or Padding round, fall back to video only
801 // composition and release all assigned non VIG pipes from primary.
802 if(isSecondaryConfiguring(ctx)) {
803 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
804 __FUNCTION__);
805 return false;
806 } else if(ctx->isPaddingRound) {
807 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
808 __FUNCTION__,mDpy);
809 return false;
810 }
811
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700812 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800813 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700814 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800815 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
816 return false;
817 }
818
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800819 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800820 hwc_layer_1_t* layer = &list->hwLayers[i];
821 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800822
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800823 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700824 if(!canUseRotator(ctx, mDpy)) {
825 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
826 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700827 return false;
828 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800829 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530830
831 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
832 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800833 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700834 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530835 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
836 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
837 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800838 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700839
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700840 if(ctx->mAD->isDoable()) {
841 return false;
842 }
843
Saurabh Shahaa236822013-04-24 18:07:26 -0700844 //If all above hard conditions are met we can do full or partial MDP comp.
845 bool ret = false;
846 if(fullMDPComp(ctx, list)) {
847 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700848 } else if(fullMDPCompWithPTOR(ctx, list)) {
849 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700850 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700851 ret = true;
852 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530853
Saurabh Shahaa236822013-04-24 18:07:26 -0700854 return ret;
855}
856
857bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700858
859 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
860 return false;
861
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700862 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
863 for(int i = 0; i < numAppLayers; i++) {
864 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700865 if(not mCurrentFrame.drop[i] and
866 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700867 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
868 return false;
869 }
870 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800871
Saurabh Shahaa236822013-04-24 18:07:26 -0700872 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700873 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
874 sizeof(mCurrentFrame.isFBComposed));
875 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
876 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700877
Raj Kamal389d6e32014-08-04 14:43:24 +0530878 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800879 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530880 }
881
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800882 if(!postHeuristicsHandling(ctx, list)) {
883 ALOGD_IF(isDebug(), "post heuristic handling failed");
884 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700885 return false;
886 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700887 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
888 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700889 return true;
890}
891
Sushil Chauhandefd3522014-05-13 18:17:12 -0700892/* Full MDP Composition with Peripheral Tiny Overlap Removal.
893 * MDP bandwidth limitations can be avoided, if the overlap region
894 * covered by the smallest layer at a higher z-order, gets composed
895 * by Copybit on a render buffer, which can be queued to MDP.
896 */
897bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
898 hwc_display_contents_1_t* list) {
899
900 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
901 const int stagesForMDP = min(sMaxPipesPerMixer,
902 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
903
904 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700905 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700906 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
907 return false;
908 }
909
910 // Frame level checks
911 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
912 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
913 isSecurePresent(ctx, mDpy)) {
914 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
915 return false;
916 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700917 // MDP comp checks
918 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700919 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700920 if(not isSupportedForMDPComp(ctx, layer)) {
921 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
922 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700923 }
924 }
925
Sushil Chauhandefd3522014-05-13 18:17:12 -0700926 /* We cannot use this composition mode, if:
927 1. A below layer needs scaling.
928 2. Overlap is not peripheral to display.
929 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700930 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700931 */
932
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700933 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
934 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
935 memset(overlapRect, 0, sizeof(overlapRect));
936 int layerPixelCount, minPixelCount = 0;
937 int numPTORLayersFound = 0;
938 for (int i = numAppLayers-1; (i >= 0 &&
939 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700940 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700941 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700942 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700943 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
944 // PTOR layer should be peripheral and cannot have transform
945 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
946 has90Transform(layer)) {
947 continue;
948 }
949 if((3 * (layerPixelCount + minPixelCount)) >
950 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
951 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
952 continue;
953 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700954 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700955 for (int j = i-1; j >= 0; j--) {
956 // Check if the layers below this layer qualifies for PTOR comp
957 hwc_layer_1_t* layer = &list->hwLayers[j];
958 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700959 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700960 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700961 if (isValidRect(getIntersection(dispFrame, disFrame))) {
962 if (has90Transform(layer) || needsScaling(layer)) {
963 found = false;
964 break;
965 }
966 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700967 }
968 }
969 // Store the minLayer Index
970 if(found) {
971 minLayerIndex[numPTORLayersFound] = i;
972 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
973 minPixelCount += layerPixelCount;
974 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700975 }
976 }
977
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700978 // No overlap layers
979 if (!numPTORLayersFound)
980 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700981
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700982 // Store the displayFrame and the sourceCrops of the layers
983 hwc_rect_t displayFrame[numAppLayers];
984 hwc_rect_t sourceCrop[numAppLayers];
985 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700986 hwc_layer_1_t* layer = &list->hwLayers[i];
987 displayFrame[i] = layer->displayFrame;
988 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700989 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700990
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530991 /**
992 * It's possible that 2 PTOR layers might have overlapping.
993 * In such case, remove the intersection(again if peripheral)
994 * from the lower PTOR layer to avoid overlapping.
995 * If intersection is not on peripheral then compromise
996 * by reducing number of PTOR layers.
997 **/
998 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
999 if(isValidRect(commonRect)) {
1000 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1001 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1002 }
1003
1004 ctx->mPtorInfo.count = numPTORLayersFound;
1005 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1006 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1007 }
1008
1009 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1010 // reset PTOR
1011 ctx->mPtorInfo.count = 0;
1012 if(isValidRect(commonRect)) {
1013 // If PTORs are intersecting restore displayframe of PTOR[1]
1014 // before returning, as we have modified it above.
1015 list->hwLayers[minLayerIndex[1]].displayFrame =
1016 displayFrame[minLayerIndex[1]];
1017 }
1018 return false;
1019 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001020 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1021 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1022
Xu Yangcda012c2014-07-30 21:57:21 +08001023 // Store the blending mode, planeAlpha, and transform of PTOR layers
1024 int32_t blending[numPTORLayersFound];
1025 uint8_t planeAlpha[numPTORLayersFound];
1026 uint32_t transform[numPTORLayersFound];
1027
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001028 for(int j = 0; j < numPTORLayersFound; j++) {
1029 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001030
1031 // Update src crop of PTOR layer
1032 hwc_layer_1_t* layer = &list->hwLayers[index];
1033 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1034 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1035 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1036 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1037
1038 // Store & update w, h, format of PTOR layer
1039 private_handle_t *hnd = (private_handle_t *)layer->handle;
1040 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1041 layerWhf[j] = whf;
1042 hnd->width = renderBuf->width;
1043 hnd->height = renderBuf->height;
1044 hnd->format = renderBuf->format;
1045
Xu Yangcda012c2014-07-30 21:57:21 +08001046 // Store & update blending mode, planeAlpha and transform of PTOR layer
1047 blending[j] = layer->blending;
1048 planeAlpha[j] = layer->planeAlpha;
1049 transform[j] = layer->transform;
1050 layer->blending = HWC_BLENDING_NONE;
1051 layer->planeAlpha = 0xFF;
1052 layer->transform = 0;
1053
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001054 // Remove overlap from crop & displayFrame of below layers
1055 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001056 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001057 if(!isValidRect(getIntersection(layer->displayFrame,
1058 overlapRect[j]))) {
1059 continue;
1060 }
1061 // Update layer attributes
1062 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1063 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301064 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001065 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1066 layer->transform);
1067 layer->sourceCropf.left = (float)srcCrop.left;
1068 layer->sourceCropf.top = (float)srcCrop.top;
1069 layer->sourceCropf.right = (float)srcCrop.right;
1070 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1071 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001072 }
1073
1074 mCurrentFrame.mdpCount = numAppLayers;
1075 mCurrentFrame.fbCount = 0;
1076 mCurrentFrame.fbZ = -1;
1077
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301078 for (int j = 0; j < numAppLayers; j++) {
1079 if(isValidRect(list->hwLayers[j].displayFrame)) {
1080 mCurrentFrame.isFBComposed[j] = false;
1081 } else {
1082 mCurrentFrame.mdpCount--;
1083 mCurrentFrame.drop[j] = true;
1084 }
1085 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001086
1087 bool result = postHeuristicsHandling(ctx, list);
1088
1089 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001090 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001091 hwc_layer_1_t* layer = &list->hwLayers[i];
1092 layer->displayFrame = displayFrame[i];
1093 layer->sourceCropf.left = (float)sourceCrop[i].left;
1094 layer->sourceCropf.top = (float)sourceCrop[i].top;
1095 layer->sourceCropf.right = (float)sourceCrop[i].right;
1096 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1097 }
1098
Xu Yangcda012c2014-07-30 21:57:21 +08001099 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001100 for (int i = 0; i < numPTORLayersFound; i++) {
1101 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001102 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001103 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1104 hnd->width = layerWhf[i].w;
1105 hnd->height = layerWhf[i].h;
1106 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001107 layer->blending = blending[i];
1108 layer->planeAlpha = planeAlpha[i];
1109 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001110 }
1111
Sushil Chauhandefd3522014-05-13 18:17:12 -07001112 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001113 // reset PTOR
1114 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001115 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001116 } else {
1117 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1118 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001119 }
1120
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001121 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1122 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001123 return result;
1124}
1125
Saurabh Shahaa236822013-04-24 18:07:26 -07001126bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1127{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001128 if(!sEnableMixedMode) {
1129 //Mixed mode is disabled. No need to even try caching.
1130 return false;
1131 }
1132
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001133 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001134 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001135 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001136 cacheBasedComp(ctx, list);
1137 } else {
1138 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001139 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001140 }
1141
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001142 return ret;
1143}
1144
1145bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1146 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001147 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1148 return false;
1149
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001150 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001151 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001152 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001153
1154 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1155 for(int i = 0; i < numAppLayers; i++) {
1156 if(!mCurrentFrame.isFBComposed[i]) {
1157 hwc_layer_1_t* layer = &list->hwLayers[i];
1158 if(not isSupportedForMDPComp(ctx, layer)) {
1159 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1160 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001161 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001162 return false;
1163 }
1164 }
1165 }
1166
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001167 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001168 /* mark secure RGB layers for MDP comp */
1169 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301170 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001171 if(!ret) {
1172 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001173 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001174 return false;
1175 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001176
1177 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001178
Raj Kamal389d6e32014-08-04 14:43:24 +05301179 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001180 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301181 }
1182
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001183 if(!postHeuristicsHandling(ctx, list)) {
1184 ALOGD_IF(isDebug(), "post heuristic handling failed");
1185 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001186 return false;
1187 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001188 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1189 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001190
Saurabh Shahaa236822013-04-24 18:07:26 -07001191 return true;
1192}
1193
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001194bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001195 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001196 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1197 return false;
1198
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001199 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001200 return false;
1201 }
1202
Saurabh Shahb772ae32013-11-18 15:40:02 -08001203 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001204 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1205 const int stagesForMDP = min(sMaxPipesPerMixer,
1206 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001207
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001208 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1209 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1210 int lastMDPSupportedIndex = numAppLayers;
1211 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001212
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001213 //Find the minimum MDP batch size
1214 for(int i = 0; i < numAppLayers;i++) {
1215 if(mCurrentFrame.drop[i]) {
1216 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001217 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001218 }
1219 hwc_layer_1_t* layer = &list->hwLayers[i];
1220 if(not isSupportedForMDPComp(ctx, layer)) {
1221 lastMDPSupportedIndex = i;
1222 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1223 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001224 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001225 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001226 }
1227
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001228 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1229 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1230 mCurrentFrame.dropCount);
1231
1232 //Start at a point where the fb batch should at least have 2 layers, for
1233 //this mode to be justified.
1234 while(fbBatchSize < 2) {
1235 ++fbBatchSize;
1236 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001237 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001238
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001239 //If there are no layers for MDP, this mode doesnt make sense.
1240 if(mdpBatchSize < 1) {
1241 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1242 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001243 return false;
1244 }
1245
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001246 mCurrentFrame.reset(numAppLayers);
1247
1248 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1249 while(mdpBatchSize > 0) {
1250 //Mark layers for MDP comp
1251 int mdpBatchLeft = mdpBatchSize;
1252 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1253 if(mCurrentFrame.drop[i]) {
1254 continue;
1255 }
1256 mCurrentFrame.isFBComposed[i] = false;
1257 --mdpBatchLeft;
1258 }
1259
1260 mCurrentFrame.fbZ = mdpBatchSize;
1261 mCurrentFrame.fbCount = fbBatchSize;
1262 mCurrentFrame.mdpCount = mdpBatchSize;
1263
1264 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1265 __FUNCTION__, mdpBatchSize, fbBatchSize,
1266 mCurrentFrame.dropCount);
1267
1268 if(postHeuristicsHandling(ctx, list)) {
1269 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001270 __FUNCTION__);
1271 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1272 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001273 return true;
1274 }
1275
1276 reset(ctx);
1277 --mdpBatchSize;
1278 ++fbBatchSize;
1279 }
1280
1281 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001282}
1283
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001284bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301285 if(mDpy or isSecurePresent(ctx, mDpy) or
1286 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001287 return false;
1288 }
1289 return true;
1290}
1291
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001292bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1293 hwc_display_contents_1_t* list){
1294 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1295 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001296 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001297 return false;
1298 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001299 if(ctx->listStats[mDpy].secureUI)
1300 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001301 return true;
1302}
1303
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001304bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1305 hwc_display_contents_1_t* list) {
1306 const bool secureOnly = true;
1307 return videoOnlyComp(ctx, list, not secureOnly) or
1308 videoOnlyComp(ctx, list, secureOnly);
1309}
1310
1311bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001312 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001313 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1314 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301315
Saurabh Shahaa236822013-04-24 18:07:26 -07001316 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301317 if(!isSecurePresent(ctx, mDpy)) {
1318 /* Bail out if we are processing only secured video layers
1319 * and we dont have any */
1320 if(secureOnly) {
1321 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1322 return false;
1323 }
1324 /* No Idle fall back for secure video layers and if there is only
1325 * single layer being composed. */
1326 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1327 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1328 return false;
1329 }
1330 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001331
Saurabh Shahaa236822013-04-24 18:07:26 -07001332 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001333 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001334 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001335 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001336
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001337 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1338 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001339 return false;
1340 }
1341
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001342 if(mCurrentFrame.fbCount)
1343 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001344
Raj Kamal389d6e32014-08-04 14:43:24 +05301345 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001346 adjustForSourceSplit(ctx, list);
1347 }
1348
1349 if(!postHeuristicsHandling(ctx, list)) {
1350 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301351 if(errno == ENOBUFS) {
1352 ALOGD_IF(isDebug(), "SMP Allocation failed");
1353 //On SMP allocation failure in video only comp add padding round
1354 ctx->isPaddingRound = true;
1355 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001356 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001357 return false;
1358 }
1359
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001360 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1361 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001362 return true;
1363}
1364
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001365/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1366bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1367 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001368 // Fall back to video only composition, if AIV video mode is enabled
1369 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001370 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1371 __FUNCTION__, mDpy);
1372 return false;
1373 }
1374
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001375 const bool secureOnly = true;
1376 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1377 mdpOnlyLayersComp(ctx, list, secureOnly);
1378
1379}
1380
1381bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1382 hwc_display_contents_1_t* list, bool secureOnly) {
1383
1384 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1385 return false;
1386
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301387 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1388 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1389 /* Bail out if we are processing only secured video/ui layers
1390 * and we dont have any */
1391 if(secureOnly) {
1392 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1393 return false;
1394 }
1395 /* No Idle fall back for secure video/ui layers and if there is only
1396 * single layer being composed. */
1397 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1398 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1399 return false;
1400 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001401 }
1402
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001403 /* Bail out if we dont have any secure RGB layers */
1404 if (!ctx->listStats[mDpy].secureRGBCount) {
1405 reset(ctx);
1406 return false;
1407 }
1408
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001409 mCurrentFrame.reset(numAppLayers);
1410 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1411
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001412 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001413 /* mark secure RGB layers for MDP comp */
1414 updateSecureRGB(ctx, list);
1415
1416 if(mCurrentFrame.mdpCount == 0) {
1417 reset(ctx);
1418 return false;
1419 }
1420
1421 /* find the maximum batch of layers to be marked for framebuffer */
1422 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1423 if(!ret) {
1424 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1425 reset(ctx);
1426 return false;
1427 }
1428
1429 if(sEnableYUVsplit){
1430 adjustForSourceSplit(ctx, list);
1431 }
1432
1433 if(!postHeuristicsHandling(ctx, list)) {
1434 ALOGD_IF(isDebug(), "post heuristic handling failed");
1435 reset(ctx);
1436 return false;
1437 }
1438
1439 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1440 __FUNCTION__);
1441 return true;
1442}
1443
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001444/* Checks for conditions where YUV layers cannot be bypassed */
1445bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001446 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001447 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001448 return false;
1449 }
1450
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001451 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001452 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1453 return false;
1454 }
1455
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001456 if(isSecuring(ctx, layer)) {
1457 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1458 return false;
1459 }
1460
Saurabh Shah4fdde762013-04-30 18:47:33 -07001461 if(!isValidDimension(ctx, layer)) {
1462 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1463 __FUNCTION__);
1464 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001465 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001466
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001467 if(layer->planeAlpha < 0xFF) {
1468 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1469 in video only mode",
1470 __FUNCTION__);
1471 return false;
1472 }
1473
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001474 return true;
1475}
1476
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001477/* Checks for conditions where Secure RGB layers cannot be bypassed */
1478bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1479 if(isSkipLayer(layer)) {
1480 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1481 __FUNCTION__, mDpy);
1482 return false;
1483 }
1484
1485 if(isSecuring(ctx, layer)) {
1486 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1487 return false;
1488 }
1489
1490 if(not isSupportedForMDPComp(ctx, layer)) {
1491 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1492 __FUNCTION__);
1493 return false;
1494 }
1495 return true;
1496}
1497
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301498/* starts at fromIndex and check for each layer to find
1499 * if it it has overlapping with any Updating layer above it in zorder
1500 * till the end of the batch. returns true if it finds any intersection */
1501bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1502 int fromIndex, int toIndex) {
1503 for(int i = fromIndex; i < toIndex; i++) {
1504 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1505 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1506 return false;
1507 }
1508 }
1509 }
1510 return true;
1511}
1512
1513/* Checks if given layer at targetLayerIndex has any
1514 * intersection with all the updating layers in beween
1515 * fromIndex and toIndex. Returns true if it finds intersectiion */
1516bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1517 int fromIndex, int toIndex, int targetLayerIndex) {
1518 for(int i = fromIndex; i <= toIndex; i++) {
1519 if(!mCurrentFrame.isFBComposed[i]) {
1520 if(areLayersIntersecting(&list->hwLayers[i],
1521 &list->hwLayers[targetLayerIndex])) {
1522 return true;
1523 }
1524 }
1525 }
1526 return false;
1527}
1528
1529int MDPComp::getBatch(hwc_display_contents_1_t* list,
1530 int& maxBatchStart, int& maxBatchEnd,
1531 int& maxBatchCount) {
1532 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301533 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001534 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301535 while (i < mCurrentFrame.layerCount) {
1536 int batchCount = 0;
1537 int batchStart = i;
1538 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001539 /* Adjust batch Z order with the dropped layers so far */
1540 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301541 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301542 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301543 while(i < mCurrentFrame.layerCount) {
1544 if(!mCurrentFrame.isFBComposed[i]) {
1545 if(!batchCount) {
1546 i++;
1547 break;
1548 }
1549 updatingLayersAbove++;
1550 i++;
1551 continue;
1552 } else {
1553 if(mCurrentFrame.drop[i]) {
1554 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001555 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301556 continue;
1557 } else if(updatingLayersAbove <= 0) {
1558 batchCount++;
1559 batchEnd = i;
1560 i++;
1561 continue;
1562 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1563
1564 // We have a valid updating layer already. If layer-i not
1565 // have overlapping with all updating layers in between
1566 // batch-start and i, then we can add layer i to batch.
1567 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1568 batchCount++;
1569 batchEnd = i;
1570 i++;
1571 continue;
1572 } else if(canPushBatchToTop(list, batchStart, i)) {
1573 //If All the non-updating layers with in this batch
1574 //does not have intersection with the updating layers
1575 //above in z-order, then we can safely move the batch to
1576 //higher z-order. Increment fbZ as it is moving up.
1577 if( firstZReverseIndex < 0) {
1578 firstZReverseIndex = i;
1579 }
1580 batchCount++;
1581 batchEnd = i;
1582 fbZ += updatingLayersAbove;
1583 i++;
1584 updatingLayersAbove = 0;
1585 continue;
1586 } else {
1587 //both failed.start the loop again from here.
1588 if(firstZReverseIndex >= 0) {
1589 i = firstZReverseIndex;
1590 }
1591 break;
1592 }
1593 }
1594 }
1595 }
1596 if(batchCount > maxBatchCount) {
1597 maxBatchCount = batchCount;
1598 maxBatchStart = batchStart;
1599 maxBatchEnd = batchEnd;
1600 fbZOrder = fbZ;
1601 }
1602 }
1603 return fbZOrder;
1604}
1605
1606bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1607 hwc_display_contents_1_t* list) {
1608 /* Idea is to keep as many non-updating(cached) layers in FB and
1609 * send rest of them through MDP. This is done in 2 steps.
1610 * 1. Find the maximum contiguous batch of non-updating layers.
1611 * 2. See if we can improve this batch size for caching by adding
1612 * opaque layers around the batch, if they don't have
1613 * any overlapping with the updating layers in between.
1614 * NEVER mark an updating layer for caching.
1615 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616
1617 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001618 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301620 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001622 /* Nothing is cached. No batching needed */
1623 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001624 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001625 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001626
1627 /* No MDP comp layers, try to use other comp modes */
1628 if(mCurrentFrame.mdpCount == 0) {
1629 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001630 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001631
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301632 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001633
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301634 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001635 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001636 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001637 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301638 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001639 if(!mCurrentFrame.drop[i]){
1640 //If an unsupported layer is being attempted to
1641 //be pulled out we should fail
1642 if(not isSupportedForMDPComp(ctx, layer)) {
1643 return false;
1644 }
1645 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001646 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001647 }
1648 }
1649
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301650 // update the frame data
1651 mCurrentFrame.fbZ = fbZ;
1652 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001653 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001654 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001655
1656 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301657 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001658
1659 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001661
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001662void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001663 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001664 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001665 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001667 for(int i = 0; i < numAppLayers; i++) {
1668 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001669 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001670 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001671 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001673 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001674 }
1675 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001676
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001677 frame.fbCount = fbCount;
1678 frame.mdpCount = frame.layerCount - frame.fbCount
1679 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001680
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001681 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1682 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001683}
1684
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001685// drop other non-AIV layers from external display list.
1686void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001687 hwc_display_contents_1_t* list) {
1688 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1689 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001690 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001691 mCurrentFrame.dropCount++;
1692 mCurrentFrame.drop[i] = true;
1693 }
1694 }
1695 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1696 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1697 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1698 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1699 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1700 mCurrentFrame.dropCount);
1701}
1702
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001703void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001704 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001705 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1706 for(int index = 0;index < nYuvCount; index++){
1707 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1708 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1709
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001710 if(mCurrentFrame.drop[nYuvIndex]) {
1711 continue;
1712 }
1713
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001714 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001715 if(!frame.isFBComposed[nYuvIndex]) {
1716 frame.isFBComposed[nYuvIndex] = true;
1717 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001718 }
1719 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001720 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001721 private_handle_t *hnd = (private_handle_t *)layer->handle;
1722 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001723 frame.isFBComposed[nYuvIndex] = false;
1724 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001725 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001726 }
1727 }
1728 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001729
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001730 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1731 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001732}
1733
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001734void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1735 hwc_display_contents_1_t* list) {
1736 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1737 for(int index = 0;index < nSecureRGBCount; index++){
1738 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1739 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1740
1741 if(!isSecureRGBDoable(ctx, layer)) {
1742 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1743 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1744 mCurrentFrame.fbCount++;
1745 }
1746 } else {
1747 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1748 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1749 mCurrentFrame.fbCount--;
1750 }
1751 }
1752 }
1753
1754 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1755 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1756 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1757 mCurrentFrame.fbCount);
1758}
1759
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001760hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1761 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001762 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001763
1764 /* Update only the region of FB needed for composition */
1765 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1766 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1767 hwc_layer_1_t* layer = &list->hwLayers[i];
1768 hwc_rect_t dst = layer->displayFrame;
1769 fbRect = getUnion(fbRect, dst);
1770 }
1771 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001772 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001773 return fbRect;
1774}
1775
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001776bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1777 hwc_display_contents_1_t* list) {
1778
1779 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001780 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001781 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1782 return false;
1783 }
1784
1785 //Limitations checks
1786 if(!hwLimitationsCheck(ctx, list)) {
1787 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1788 return false;
1789 }
1790
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001791 //Configure framebuffer first if applicable
1792 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001793 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001794 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1795 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001796 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1797 __FUNCTION__);
1798 return false;
1799 }
1800 }
1801
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001802 mCurrentFrame.map();
1803
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001804 if(!allocLayerPipes(ctx, list)) {
1805 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001806 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001807 }
1808
1809 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001810 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001811 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001812 int mdpIndex = mCurrentFrame.layerToMDP[index];
1813 hwc_layer_1_t* layer = &list->hwLayers[index];
1814
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301815 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1816 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1817 mdpNextZOrder++;
1818 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001819 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1820 cur_pipe->zOrder = mdpNextZOrder++;
1821
radhakrishnac9a67412013-09-25 17:40:42 +05301822 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301823 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301824 if(configure4k2kYuv(ctx, layer,
1825 mCurrentFrame.mdpToLayer[mdpIndex])
1826 != 0 ){
1827 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1828 for layer %d",__FUNCTION__, index);
1829 return false;
1830 }
1831 else{
1832 mdpNextZOrder++;
1833 }
1834 continue;
1835 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001836 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1837 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301838 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001839 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001840 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001841 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001842 }
1843
Saurabh Shaha36be922013-12-16 18:18:39 -08001844 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1845 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1846 ,__FUNCTION__, mDpy);
1847 return false;
1848 }
1849
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001850 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001851 return true;
1852}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001853
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001854bool MDPComp::resourceCheck(hwc_context_t* ctx,
1855 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001856 const bool fbUsed = mCurrentFrame.fbCount;
1857 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1858 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1859 return false;
1860 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001861
1862 //Will benefit cases where a video has non-updating background.
1863 if((mDpy > HWC_DISPLAY_PRIMARY) and
1864 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1865 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1866 return false;
1867 }
1868
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001869 // Init rotCount to number of rotate sessions used by other displays
1870 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1871 // Count the number of rotator sessions required for current display
1872 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1873 if(!mCurrentFrame.isFBComposed[index]) {
1874 hwc_layer_1_t* layer = &list->hwLayers[index];
1875 private_handle_t *hnd = (private_handle_t *)layer->handle;
1876 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1877 rotCount++;
1878 }
1879 }
1880 }
1881 // if number of layers to rotate exceeds max rotator sessions, bail out.
1882 if(rotCount > RotMgr::MAX_ROT_SESS) {
1883 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1884 __FUNCTION__, mDpy);
1885 return false;
1886 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001887 return true;
1888}
1889
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301890bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1891 hwc_display_contents_1_t* list) {
1892
1893 //A-family hw limitation:
1894 //If a layer need alpha scaling, MDP can not support.
1895 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1896 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1897 if(!mCurrentFrame.isFBComposed[i] &&
1898 isAlphaScaled( &list->hwLayers[i])) {
1899 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1900 return false;
1901 }
1902 }
1903 }
1904
1905 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1906 //If multiple layers requires downscaling and also they are overlapping
1907 //fall back to GPU since MDSS can not handle it.
1908 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1909 qdutils::MDPVersion::getInstance().is8x26()) {
1910 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1911 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1912 if(!mCurrentFrame.isFBComposed[i] &&
1913 isDownscaleRequired(botLayer)) {
1914 //if layer-i is marked for MDP and needs downscaling
1915 //check if any MDP layer on top of i & overlaps with layer-i
1916 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1917 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1918 if(!mCurrentFrame.isFBComposed[j] &&
1919 isDownscaleRequired(topLayer)) {
1920 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1921 topLayer->displayFrame);
1922 if(isValidRect(r))
1923 return false;
1924 }
1925 }
1926 }
1927 }
1928 }
1929 return true;
1930}
1931
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001932// Checks only if videos or single layer(RGB) is updating
1933// which is used for setting dynamic fps or perf hint for single
1934// layer video playback
1935bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1936 hwc_display_contents_1_t* list) {
1937 bool support = false;
1938 FrameInfo frame;
1939 frame.reset(mCurrentFrame.layerCount);
1940 memset(&frame.drop, 0, sizeof(frame.drop));
1941 frame.dropCount = 0;
1942 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1943 updateLayerCache(ctx, list, frame);
1944 updateYUV(ctx, list, false /*secure only*/, frame);
1945 // There are only updating YUV layers or there is single RGB
1946 // Layer(Youtube)
1947 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1948 (frame.layerCount == 1)) {
1949 support = true;
1950 }
1951 return support;
1952}
1953
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301954void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1955 //For primary display, set the dynamic refreshrate
1956 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1957 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301958 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1959 MDPVersion& mdpHw = MDPVersion::getInstance();
1960 if(sIdleFallBack) {
1961 //Set minimum panel refresh rate during idle timeout
1962 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001963 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301964 //Set the new fresh rate, if there is only one updating YUV layer
1965 //or there is one single RGB layer with this request
1966 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1967 }
1968 setRefreshRate(ctx, mDpy, refreshRate);
1969 }
1970}
1971
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001972int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001973 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001974 char property[PROPERTY_VALUE_MAX];
1975
Raj Kamal4393eaa2014-06-06 13:45:20 +05301976 if(!ctx || !list) {
1977 ALOGE("%s: Invalid context or list",__FUNCTION__);
1978 mCachedFrame.reset();
1979 return -1;
1980 }
1981
1982 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001983 if(mDpy == HWC_DISPLAY_PRIMARY) {
1984 sSimulationFlags = 0;
1985 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1986 int currentFlags = atoi(property);
1987 if(currentFlags != sSimulationFlags) {
1988 sSimulationFlags = currentFlags;
1989 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1990 sSimulationFlags, sSimulationFlags);
1991 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001992 }
1993 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001994 // reset PTOR
1995 if(!mDpy)
1996 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001997
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301998 //reset old data
1999 mCurrentFrame.reset(numLayers);
2000 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2001 mCurrentFrame.dropCount = 0;
2002
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302003 //Do not cache the information for next draw cycle.
2004 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2005 ALOGI("%s: Unsupported layer count for mdp composition",
2006 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002007 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302008#ifdef DYNAMIC_FPS
2009 setDynRefreshRate(ctx, list);
2010#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002011 return -1;
2012 }
2013
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002014 // Detect the start of animation and fall back to GPU only once to cache
2015 // all the layers in FB and display FB content untill animation completes.
2016 if(ctx->listStats[mDpy].isDisplayAnimating) {
2017 mCurrentFrame.needsRedraw = false;
2018 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2019 mCurrentFrame.needsRedraw = true;
2020 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2021 }
2022 setMDPCompLayerFlags(ctx, list);
2023 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302024#ifdef DYNAMIC_FPS
2025 setDynRefreshRate(ctx, list);
2026#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002027 ret = -1;
2028 return ret;
2029 } else {
2030 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2031 }
2032
Saurabh Shahb39f8152013-08-22 10:21:44 -07002033 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002034 if(isFrameDoable(ctx)) {
2035 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002036 // if AIV Video mode is enabled, drop all non AIV layers from the
2037 // external display list.
2038 if(ctx->listStats[mDpy].mAIVVideoMode) {
2039 dropNonAIVLayers(ctx, list);
2040 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002041
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002042 // if tryFullFrame fails, try to push all video and secure RGB layers
2043 // to MDP for composition.
2044 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002045 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302046 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002047 setMDPCompLayerFlags(ctx, list);
2048 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002049 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002050 reset(ctx);
2051 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2052 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002053 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002054 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2055 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002056 }
2057 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302058 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2059 enablePartialUpdateForMDP3) {
2060 generateROI(ctx, list);
2061 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2062 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2063 }
2064 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002065 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2066 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002067 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002068 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002069
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002070 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002071 ALOGD("GEOMETRY change: %d",
2072 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002073 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002074 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002075 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002076 }
2077
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002078#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302079 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002080#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002081 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002082
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002083 mCachedFrame.cacheAll(list);
2084 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002085 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002086}
2087
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002088bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302089
2090 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302091 int mdpIndex = mCurrentFrame.layerToMDP[index];
2092 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2093 info.pipeInfo = new MdpYUVPipeInfo;
2094 info.rot = NULL;
2095 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302096
2097 pipe_info.lIndex = ovutils::OV_INVALID;
2098 pipe_info.rIndex = ovutils::OV_INVALID;
2099
Saurabh Shahc62f3982014-03-05 14:28:26 -08002100 Overlay::PipeSpecs pipeSpecs;
2101 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2102 pipeSpecs.needsScaling = true;
2103 pipeSpecs.dpy = mDpy;
2104 pipeSpecs.fb = false;
2105
2106 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302107 if(pipe_info.lIndex == ovutils::OV_INVALID){
2108 bRet = false;
2109 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2110 __FUNCTION__);
2111 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002112 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302113 if(pipe_info.rIndex == ovutils::OV_INVALID){
2114 bRet = false;
2115 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2116 __FUNCTION__);
2117 }
2118 return bRet;
2119}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002120
2121int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2122 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002123 if (ctx->mPtorInfo.isActive()) {
2124 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002125 if (fd < 0) {
2126 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002127 }
2128 }
2129 return fd;
2130}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002131//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002132
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002133void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302134 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002135 //If 4k2k Yuv layer split is possible, and if
2136 //fbz is above 4k2k layer, increment fb zorder by 1
2137 //as we split 4k2k layer and increment zorder for right half
2138 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002139 if(!ctx)
2140 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002141 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302142 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2143 index++) {
2144 if(!mCurrentFrame.isFBComposed[index]) {
2145 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2146 mdpNextZOrder++;
2147 }
2148 mdpNextZOrder++;
2149 hwc_layer_1_t* layer = &list->hwLayers[index];
2150 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302151 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302152 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2153 mCurrentFrame.fbZ += 1;
2154 mdpNextZOrder++;
2155 //As we split 4kx2k yuv layer and program to 2 VG pipes
2156 //(if available) increase mdpcount by 1.
2157 mCurrentFrame.mdpCount++;
2158 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002159 }
2160 }
2161 }
radhakrishnac9a67412013-09-25 17:40:42 +05302162}
2163
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002164/*
2165 * Configures pipe(s) for MDP composition
2166 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002167int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002168 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002169 MdpPipeInfoNonSplit& mdp_info =
2170 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302171 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002172 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002173 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002174
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002175 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2176 __FUNCTION__, layer, zOrder, dest);
2177
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002178 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002179 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002180}
2181
Saurabh Shah88e4d272013-09-03 13:31:29 -07002182bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002183 hwc_display_contents_1_t* list) {
2184 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002185
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002186 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002187
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002188 hwc_layer_1_t* layer = &list->hwLayers[index];
2189 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302190 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002191 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302192 continue;
2193 }
2194 }
2195
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002196 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002197 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002198 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002199 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002200 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002201
Saurabh Shahc62f3982014-03-05 14:28:26 -08002202 Overlay::PipeSpecs pipeSpecs;
2203 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2204 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2205 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2206 (qdutils::MDPVersion::getInstance().is8x26() and
2207 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2208 pipeSpecs.dpy = mDpy;
2209 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002210 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002211
Saurabh Shahc62f3982014-03-05 14:28:26 -08002212 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2213
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002214 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002215 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002216 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002217 }
2218 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002219 return true;
2220}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002221
radhakrishnac9a67412013-09-25 17:40:42 +05302222int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2223 PipeLayerPair& PipeLayerPair) {
2224 MdpYUVPipeInfo& mdp_info =
2225 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2226 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302227 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302228 eDest lDest = mdp_info.lIndex;
2229 eDest rDest = mdp_info.rIndex;
2230
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002231 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302232 lDest, rDest, &PipeLayerPair.rot);
2233}
2234
Saurabh Shah88e4d272013-09-03 13:31:29 -07002235bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002236
Raj Kamal4393eaa2014-06-06 13:45:20 +05302237 if(!isEnabled() or !mModeOn) {
2238 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302239 return true;
2240 }
2241
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002242 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002243 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002244 sHandleTimeout = true;
2245 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002246
2247 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002248 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002249
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002250 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2251 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002252 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002253 if(mCurrentFrame.isFBComposed[i]) continue;
2254
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002255 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002256 private_handle_t *hnd = (private_handle_t *)layer->handle;
2257 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002258 if (!(layer->flags & HWC_COLOR_FILL)) {
2259 ALOGE("%s handle null", __FUNCTION__);
2260 return false;
2261 }
2262 // No PLAY for Color layer
2263 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2264 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002265 }
2266
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002267 int mdpIndex = mCurrentFrame.layerToMDP[i];
2268
Raj Kamal389d6e32014-08-04 14:43:24 +05302269 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302270 {
2271 MdpYUVPipeInfo& pipe_info =
2272 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2273 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2274 ovutils::eDest indexL = pipe_info.lIndex;
2275 ovutils::eDest indexR = pipe_info.rIndex;
2276 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302277 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302278 if(rot) {
2279 rot->queueBuffer(fd, offset);
2280 fd = rot->getDstMemId();
2281 offset = rot->getDstOffset();
2282 }
2283 if(indexL != ovutils::OV_INVALID) {
2284 ovutils::eDest destL = (ovutils::eDest)indexL;
2285 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2286 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2287 if (!ov.queueBuffer(fd, offset, destL)) {
2288 ALOGE("%s: queueBuffer failed for display:%d",
2289 __FUNCTION__, mDpy);
2290 return false;
2291 }
2292 }
2293
2294 if(indexR != ovutils::OV_INVALID) {
2295 ovutils::eDest destR = (ovutils::eDest)indexR;
2296 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2297 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2298 if (!ov.queueBuffer(fd, offset, destR)) {
2299 ALOGE("%s: queueBuffer failed for display:%d",
2300 __FUNCTION__, mDpy);
2301 return false;
2302 }
2303 }
2304 }
2305 else{
2306 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002307 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302308 ovutils::eDest dest = pipe_info.index;
2309 if(dest == ovutils::OV_INVALID) {
2310 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002311 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302312 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002313
radhakrishnac9a67412013-09-25 17:40:42 +05302314 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2315 continue;
2316 }
2317
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002318 int fd = hnd->fd;
2319 uint32_t offset = (uint32_t)hnd->offset;
2320 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2321 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002322 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002323 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002324 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002325 }
2326
radhakrishnac9a67412013-09-25 17:40:42 +05302327 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2328 using pipe: %d", __FUNCTION__, layer,
2329 hnd, dest );
2330
radhakrishnac9a67412013-09-25 17:40:42 +05302331 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2332 if(rot) {
2333 if(!rot->queueBuffer(fd, offset))
2334 return false;
2335 fd = rot->getDstMemId();
2336 offset = rot->getDstOffset();
2337 }
2338
2339 if (!ov.queueBuffer(fd, offset, dest)) {
2340 ALOGE("%s: queueBuffer failed for display:%d ",
2341 __FUNCTION__, mDpy);
2342 return false;
2343 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002344 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002345
2346 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002347 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002348 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002349}
2350
Saurabh Shah88e4d272013-09-03 13:31:29 -07002351//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002352
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002353void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302354 hwc_display_contents_1_t* list){
2355 //if 4kx2k yuv layer is totally present in either in left half
2356 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302357 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302358 if(mCurrentFrame.fbZ >= 0) {
2359 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2360 index++) {
2361 if(!mCurrentFrame.isFBComposed[index]) {
2362 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2363 mdpNextZOrder++;
2364 }
2365 mdpNextZOrder++;
2366 hwc_layer_1_t* layer = &list->hwLayers[index];
2367 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302368 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302369 hwc_rect_t dst = layer->displayFrame;
2370 if((dst.left > lSplit) || (dst.right < lSplit)) {
2371 mCurrentFrame.mdpCount += 1;
2372 }
2373 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2374 mCurrentFrame.fbZ += 1;
2375 mdpNextZOrder++;
2376 }
2377 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002378 }
radhakrishnac9a67412013-09-25 17:40:42 +05302379 }
2380}
2381
Saurabh Shah88e4d272013-09-03 13:31:29 -07002382bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002383 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002384
Saurabh Shahc62f3982014-03-05 14:28:26 -08002385 const int lSplit = getLeftSplit(ctx, mDpy);
2386 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002387 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002388 pipe_info.lIndex = ovutils::OV_INVALID;
2389 pipe_info.rIndex = ovutils::OV_INVALID;
2390
Saurabh Shahc62f3982014-03-05 14:28:26 -08002391 Overlay::PipeSpecs pipeSpecs;
2392 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2393 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2394 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2395 pipeSpecs.dpy = mDpy;
2396 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2397 pipeSpecs.fb = false;
2398
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002399 // Acquire pipe only for the updating half
2400 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2401 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2402
2403 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002404 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002405 if(pipe_info.lIndex == ovutils::OV_INVALID)
2406 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002407 }
2408
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002409 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002410 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2411 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002412 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002413 return false;
2414 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002415
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002416 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002417}
2418
Saurabh Shah88e4d272013-09-03 13:31:29 -07002419bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002420 hwc_display_contents_1_t* list) {
2421 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002422
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002423 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002424
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002425 hwc_layer_1_t* layer = &list->hwLayers[index];
2426 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302427 hwc_rect_t dst = layer->displayFrame;
2428 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302429 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302430 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002431 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302432 continue;
2433 }
2434 }
2435 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002436 int mdpIndex = mCurrentFrame.layerToMDP[index];
2437 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002438 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002439 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002440 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002441
Saurabh Shahc62f3982014-03-05 14:28:26 -08002442 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2443 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2444 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002445 return false;
2446 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002447 }
2448 return true;
2449}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002450
radhakrishnac9a67412013-09-25 17:40:42 +05302451int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2452 PipeLayerPair& PipeLayerPair) {
2453 const int lSplit = getLeftSplit(ctx, mDpy);
2454 hwc_rect_t dst = layer->displayFrame;
2455 if((dst.left > lSplit)||(dst.right < lSplit)){
2456 MdpYUVPipeInfo& mdp_info =
2457 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2458 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302459 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302460 eDest lDest = mdp_info.lIndex;
2461 eDest rDest = mdp_info.rIndex;
2462
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002463 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302464 lDest, rDest, &PipeLayerPair.rot);
2465 }
2466 else{
2467 return configure(ctx, layer, PipeLayerPair);
2468 }
2469}
2470
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002471/*
2472 * Configures pipe(s) for MDP composition
2473 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002474int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002475 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002476 MdpPipeInfoSplit& mdp_info =
2477 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002478 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302479 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002480 eDest lDest = mdp_info.lIndex;
2481 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002482
2483 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002484 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002485
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002486 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002487 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002488}
2489
Saurabh Shah88e4d272013-09-03 13:31:29 -07002490bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002491
Raj Kamal4393eaa2014-06-06 13:45:20 +05302492 if(!isEnabled() or !mModeOn) {
2493 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302494 return true;
2495 }
2496
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002497 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002498 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002499 sHandleTimeout = true;
2500 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002501
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002502 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002503 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002504
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002505 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2506 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002507 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002508 if(mCurrentFrame.isFBComposed[i]) continue;
2509
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002510 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002511 private_handle_t *hnd = (private_handle_t *)layer->handle;
2512 if(!hnd) {
2513 ALOGE("%s handle null", __FUNCTION__);
2514 return false;
2515 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002516
2517 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2518 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002519 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002520
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002521 int mdpIndex = mCurrentFrame.layerToMDP[i];
2522
Raj Kamal389d6e32014-08-04 14:43:24 +05302523 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302524 {
2525 MdpYUVPipeInfo& pipe_info =
2526 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2527 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2528 ovutils::eDest indexL = pipe_info.lIndex;
2529 ovutils::eDest indexR = pipe_info.rIndex;
2530 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302531 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302532 if(rot) {
2533 rot->queueBuffer(fd, offset);
2534 fd = rot->getDstMemId();
2535 offset = rot->getDstOffset();
2536 }
2537 if(indexL != ovutils::OV_INVALID) {
2538 ovutils::eDest destL = (ovutils::eDest)indexL;
2539 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2540 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2541 if (!ov.queueBuffer(fd, offset, destL)) {
2542 ALOGE("%s: queueBuffer failed for display:%d",
2543 __FUNCTION__, mDpy);
2544 return false;
2545 }
2546 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002547
radhakrishnac9a67412013-09-25 17:40:42 +05302548 if(indexR != ovutils::OV_INVALID) {
2549 ovutils::eDest destR = (ovutils::eDest)indexR;
2550 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2551 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2552 if (!ov.queueBuffer(fd, offset, destR)) {
2553 ALOGE("%s: queueBuffer failed for display:%d",
2554 __FUNCTION__, mDpy);
2555 return false;
2556 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002557 }
2558 }
radhakrishnac9a67412013-09-25 17:40:42 +05302559 else{
2560 MdpPipeInfoSplit& pipe_info =
2561 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2562 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002563
radhakrishnac9a67412013-09-25 17:40:42 +05302564 ovutils::eDest indexL = pipe_info.lIndex;
2565 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002566
radhakrishnac9a67412013-09-25 17:40:42 +05302567 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002568 uint32_t offset = (uint32_t)hnd->offset;
2569 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2570 if (!mDpy && (index != -1)) {
2571 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2572 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002573 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002574 }
radhakrishnac9a67412013-09-25 17:40:42 +05302575
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002576 if(ctx->mAD->draw(ctx, fd, offset)) {
2577 fd = ctx->mAD->getDstFd();
2578 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002579 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002580
radhakrishnac9a67412013-09-25 17:40:42 +05302581 if(rot) {
2582 rot->queueBuffer(fd, offset);
2583 fd = rot->getDstMemId();
2584 offset = rot->getDstOffset();
2585 }
2586
2587 //************* play left mixer **********
2588 if(indexL != ovutils::OV_INVALID) {
2589 ovutils::eDest destL = (ovutils::eDest)indexL;
2590 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2591 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2592 if (!ov.queueBuffer(fd, offset, destL)) {
2593 ALOGE("%s: queueBuffer failed for left mixer",
2594 __FUNCTION__);
2595 return false;
2596 }
2597 }
2598
2599 //************* play right mixer **********
2600 if(indexR != ovutils::OV_INVALID) {
2601 ovutils::eDest destR = (ovutils::eDest)indexR;
2602 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2603 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2604 if (!ov.queueBuffer(fd, offset, destR)) {
2605 ALOGE("%s: queueBuffer failed for right mixer",
2606 __FUNCTION__);
2607 return false;
2608 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002609 }
2610 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002611
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002612 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2613 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002614
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002615 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002616}
Saurabh Shahab47c692014-02-12 18:45:57 -08002617
2618//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002619
2620bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2621 hwc_display_contents_1_t* list) {
2622 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2623 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2624
2625 for(int i = numAppLayers - 1; i >= 0; i--) {
2626 if(!isValidRect(visibleRect)) {
2627 mCurrentFrame.drop[i] = true;
2628 mCurrentFrame.dropCount++;
2629 continue;
2630 }
2631
2632 const hwc_layer_1_t* layer = &list->hwLayers[i];
2633 hwc_rect_t dstRect = layer->displayFrame;
2634 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2635
2636 if(!isValidRect(res)) {
2637 mCurrentFrame.drop[i] = true;
2638 mCurrentFrame.dropCount++;
2639 } else {
2640 /* Reset frame ROI when any layer which needs scaling also needs ROI
2641 * cropping */
2642 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2643 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2644 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2645 mCurrentFrame.dropCount = 0;
2646 return false;
2647 }
2648
2649 /* deduct any opaque region from visibleRect */
2650 if (layer->blending == HWC_BLENDING_NONE &&
2651 layer->planeAlpha == 0xFF)
2652 visibleRect = deductRect(visibleRect, res);
2653 }
2654 }
2655 return true;
2656}
2657
2658/*
2659 * HW Limitation: ping pong split can always split the ping pong output
2660 * equally across two DSI's. So the ROI programmed should be of equal width
2661 * for both the halves
2662 */
2663void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2664 hwc_display_contents_1_t* list) {
2665 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2666
2667
2668 if(!canPartialUpdate(ctx, list))
2669 return;
2670
2671 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2672 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2673 (int)ctx->dpyAttr[mDpy].yres};
2674
2675 for(int index = 0; index < numAppLayers; index++ ) {
2676 hwc_layer_1_t* layer = &list->hwLayers[index];
2677
2678 // If we have a RGB layer which needs rotation, no partial update
2679 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2680 return;
2681
2682 if ((mCachedFrame.hnd[index] != layer->handle) ||
2683 isYuvBuffer((private_handle_t *)layer->handle)) {
2684 hwc_rect_t dst = layer->displayFrame;
2685 hwc_rect_t updatingRect = dst;
2686
2687#ifdef QCOM_BSP
2688 if(!needsScaling(layer) && !layer->transform)
2689 {
2690 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2691 int x_off = dst.left - src.left;
2692 int y_off = dst.top - src.top;
2693 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2694 }
2695#endif
2696
2697 roi = getUnion(roi, updatingRect);
2698 }
2699 }
2700
2701 /* No layer is updating. Still SF wants a refresh.*/
2702 if(!isValidRect(roi))
2703 return;
2704
2705 roi = expandROIFromMidPoint(roi, fullFrame);
2706
2707 hwc_rect lFrame = fullFrame;
2708 lFrame.right /= 2;
2709 hwc_rect lRoi = getIntersection(roi, lFrame);
2710
2711 // Align ROI coordinates to panel restrictions
2712 lRoi = getSanitizeROI(lRoi, lFrame);
2713
2714 hwc_rect rFrame = fullFrame;
2715 rFrame.left = lFrame.right;
2716 hwc_rect rRoi = getIntersection(roi, rFrame);
2717
2718 // Align ROI coordinates to panel restrictions
2719 rRoi = getSanitizeROI(rRoi, rFrame);
2720
2721 roi = getUnion(lRoi, rRoi);
2722
2723 ctx->listStats[mDpy].lRoi = roi;
2724 if(!validateAndApplyROI(ctx, list))
2725 resetROI(ctx, mDpy);
2726
2727 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2728 __FUNCTION__,
2729 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2730 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2731 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2732 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2733}
2734
Saurabh Shahab47c692014-02-12 18:45:57 -08002735bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002736 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002737 private_handle_t *hnd = (private_handle_t *)layer->handle;
2738 hwc_rect_t dst = layer->displayFrame;
2739 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2740 pipe_info.lIndex = ovutils::OV_INVALID;
2741 pipe_info.rIndex = ovutils::OV_INVALID;
2742
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002743 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2744 trimAgainstROI(ctx,crop, dst);
2745
Saurabh Shahab47c692014-02-12 18:45:57 -08002746 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2747 //should have a higher priority than the right one. Pipe priorities are
2748 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002749
Saurabh Shahc62f3982014-03-05 14:28:26 -08002750 Overlay::PipeSpecs pipeSpecs;
2751 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2752 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2753 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2754 pipeSpecs.dpy = mDpy;
2755 pipeSpecs.fb = false;
2756
Saurabh Shahab47c692014-02-12 18:45:57 -08002757 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002758 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002759 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002760 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002761 }
2762
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002763 /* Use 2 pipes IF
2764 a) Layer's crop width is > 2048 or
2765 b) Layer's dest width > 2048 or
2766 c) On primary, driver has indicated with caps to split always. This is
2767 based on an empirically derived value of panel height. Applied only
2768 if the layer's width is > mixer's width
2769 */
2770
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302771 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002772 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302773 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002774 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2775 const uint32_t dstWidth = dst.right - dst.left;
2776 const uint32_t dstHeight = dst.bottom - dst.top;
2777 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002778 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002779 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2780 crop.bottom - crop.top;
2781 //Approximation to actual clock, ignoring the common factors in pipe and
2782 //mixer cases like line_time
2783 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2784 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002785
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002786 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2787 //pipe line length, we are still using 2 pipes. This is fine just because
2788 //this is source split where destination doesn't matter. Evaluate later to
2789 //see if going through all the calcs to save a pipe is worth it
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002790 if(dstWidth > mdpHw.getMaxPipeWidth() or
2791 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002792 (primarySplitAlways and
2793 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002794 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002795 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002796 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002797 }
2798
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002799 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2800 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002801 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002802 }
2803 }
2804
2805 return true;
2806}
2807
Saurabh Shahab47c692014-02-12 18:45:57 -08002808int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2809 PipeLayerPair& PipeLayerPair) {
2810 private_handle_t *hnd = (private_handle_t *)layer->handle;
2811 if(!hnd) {
2812 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2813 return -1;
2814 }
2815 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2816 MdpPipeInfoSplit& mdp_info =
2817 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2818 Rotator **rot = &PipeLayerPair.rot;
2819 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002820 eDest lDest = mdp_info.lIndex;
2821 eDest rDest = mdp_info.rIndex;
2822 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2823 hwc_rect_t dst = layer->displayFrame;
2824 int transform = layer->transform;
2825 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002826 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002827 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002828 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2829
2830 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2831 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2832
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002833 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2834 /* MDP driver crops layer coordinates against ROI in Non-Split
2835 * and Split MDP comp. But HWC needs to crop them for source split.
2836 * Reason: 1) Source split is efficient only when the final effective
2837 * load is distributed evenly across mixers.
2838 * 2) We have to know the effective width of the layer that
2839 * the ROI needs to find the no. of pipes the layer needs.
2840 */
2841 trimAgainstROI(ctx, crop, dst);
2842 }
2843
Saurabh Shahab47c692014-02-12 18:45:57 -08002844 // Handle R/B swap
2845 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2846 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2847 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2848 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2849 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2850 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002851 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002852 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2853 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002854 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002855 /* Calculate the external display position based on MDP downscale,
2856 ActionSafe, and extorientation features. */
2857 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002858
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002859 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302860 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002861 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002862
2863 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2864 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002865 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002866 }
2867
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002868 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002869 (*rot) = ctx->mRotMgr->getNext();
2870 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002871 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002872 //If the video is using a single pipe, enable BWC
2873 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002874 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2875 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002876 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002877 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002878 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002879 ALOGE("%s: configRotator failed!", __FUNCTION__);
2880 return -1;
2881 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002882 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002883 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002884 }
2885
2886 //If 2 pipes being used, divide layer into half, crop and dst
2887 hwc_rect_t cropL = crop;
2888 hwc_rect_t cropR = crop;
2889 hwc_rect_t dstL = dst;
2890 hwc_rect_t dstR = dst;
2891 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2892 cropL.right = (crop.right + crop.left) / 2;
2893 cropR.left = cropL.right;
2894 sanitizeSourceCrop(cropL, cropR, hnd);
2895
Saurabh Shahb729b192014-08-15 18:04:24 -07002896 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002897 //Swap crops on H flip since 2 pipes are being used
2898 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2899 hwc_rect_t tmp = cropL;
2900 cropL = cropR;
2901 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002902 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002903 }
2904
Saurabh Shahb729b192014-08-15 18:04:24 -07002905 //cropSwap trick: If the src and dst widths are both odd, let us say
2906 //2507, then splitting both into half would cause left width to be 1253
2907 //and right 1254. If crop is swapped because of H flip, this will cause
2908 //left crop width to be 1254, whereas left dst width remains 1253, thus
2909 //inducing a scaling that is unaccounted for. To overcome that we add 1
2910 //to the dst width if there is a cropSwap. So if the original width was
2911 //2507, the left dst width will be 1254. Even if the original width was
2912 //even for ex: 2508, the left dst width will still remain 1254.
2913 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002914 dstR.left = dstL.right;
2915 }
2916
2917 //For the mdp, since either we are pre-rotating or MDP does flips
2918 orient = OVERLAY_TRANSFORM_0;
2919 transform = 0;
2920
2921 //configure left pipe
2922 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002923 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002924 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2925 (ovutils::eBlending) getBlending(layer->blending));
2926
2927 if(configMdp(ctx->mOverlay, pargL, orient,
2928 cropL, dstL, metadata, lDest) < 0) {
2929 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2930 return -1;
2931 }
2932 }
2933
2934 //configure right pipe
2935 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002936 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002937 static_cast<eRotFlags>(rotFlags),
2938 layer->planeAlpha,
2939 (ovutils::eBlending) getBlending(layer->blending));
2940 if(configMdp(ctx->mOverlay, pargR, orient,
2941 cropR, dstR, metadata, rDest) < 0) {
2942 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2943 return -1;
2944 }
2945 }
2946
2947 return 0;
2948}
2949
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002950bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2951 Locker::Autolock _l(ctx->mDrawLock);
2952 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2953 char path[MAX_SYSFS_FILE_PATH];
2954 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2955 int fd = open(path, O_RDONLY);
2956 if(fd < 0) {
2957 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2958 return -1;
2959 }
2960 char value[4];
2961 ssize_t size_read = read(fd, value, sizeof(value)-1);
2962 if(size_read <= 0) {
2963 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2964 close(fd);
2965 return -1;
2966 }
2967 close(fd);
2968 value[size_read] = '\0';
2969 return atoi(value);
2970}
2971
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002972int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2973 Locker::Autolock _l(ctx->mDrawLock);
2974 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2975 char path[MAX_SYSFS_FILE_PATH];
2976 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2977 int fd = open(path, O_WRONLY);
2978 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002979 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002980 return -1;
2981 }
2982 char value[4];
2983 snprintf(value, sizeof(value), "%d", (int)enable);
2984 ssize_t ret = write(fd, value, strlen(value));
2985 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002986 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07002987 close(fd);
2988 return -1;
2989 }
2990 close(fd);
2991 sIsPartialUpdateActive = enable;
2992 return 0;
2993}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002994
2995bool MDPComp::loadPerfLib() {
2996 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
2997 bool success = false;
2998 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
2999 ALOGE("vendor library not set in ro.vendor.extension_library");
3000 return false;
3001 }
3002
3003 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3004 if(sLibPerfHint) {
3005 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3006 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3007 if (!sPerfLockAcquire || !sPerfLockRelease) {
3008 ALOGE("Failed to load symbols for perfLock");
3009 dlclose(sLibPerfHint);
3010 sLibPerfHint = NULL;
3011 return false;
3012 }
3013 success = true;
3014 ALOGI("Successfully Loaded perf hint API's");
3015 } else {
3016 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3017 }
3018 return success;
3019}
3020
3021void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3022 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3023 return;
3024 }
3025 static int count = sPerfHintWindow;
3026 static int perflockFlag = 0;
3027
3028 /* Send hint to mpctl when single layer is updated
3029 * for a successful number of windows. Hint release
3030 * happens immediately upon multiple layer update.
3031 */
3032 if (onlyVideosUpdating(ctx, list)) {
3033 if(count) {
3034 count--;
3035 }
3036 } else {
3037 if (perflockFlag) {
3038 perflockFlag = 0;
3039 sPerfLockRelease(sPerfLockHandle);
3040 }
3041 count = sPerfHintWindow;
3042 }
3043 if (count == 0 && !perflockFlag) {
3044 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3045 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3046 &perfHint, sizeof(perfHint)/sizeof(int));
3047 if(sPerfLockHandle < 0) {
3048 ALOGE("Perf Lock Acquire Failed");
3049 } else {
3050 perflockFlag = 1;
3051 }
3052 }
3053}
3054
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003055}; //namespace
3056