blob: b2ae7fe057c08cf10f540beadf4b3d90bfa77f0d [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08002 * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Saurabh Shah4fdde762013-04-30 18:47:33 -070019#include <math.h>
Naseer Ahmed7c958d42012-07-31 18:57:03 -070020#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050021#include <sys/ioctl.h>
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080022#include <dlfcn.h>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070023#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070029#include "hwc_copybit.h"
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070030#include "qd_utils.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080031
Saurabh Shah85234ec2013-04-12 17:09:00 -070032using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070033using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080034using namespace overlay::utils;
35namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037namespace qhwc {
38
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080039//==============MDPComp========================================================
40
Saurabh Shah59562ff2014-09-30 16:13:12 -070041IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080043bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070044bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050045bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070046bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070047int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070048int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053049bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070050bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shahacec8e42014-11-25 11:07:04 -080051int MDPComp::sMaxSecLayers = 1;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053052bool MDPComp::enablePartialUpdateForMDP3 = false;
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -070053bool MDPComp::sIsPartialUpdateActive = true;
Arun Kumar K.R299bcda2014-12-18 19:36:40 -080054void *MDPComp::sLibPerfHint = NULL;
55int MDPComp::sPerfLockHandle = 0;
56int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
57int (*MDPComp::sPerfLockRelease)(int value) = NULL;
58int MDPComp::sPerfHintWindow = -1;
59
Saurabh Shah88e4d272013-09-03 13:31:29 -070060MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070061 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
62 sSrcSplitEnabled = true;
63 return new MDPCompSrcSplit(dpy);
64 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070065 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080066 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070067 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080068}
69
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080070MDPComp::MDPComp(int dpy):mDpy(dpy){};
71
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070072void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080073{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070074 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
75 return;
76
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080077 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070078 (mDpy == 0) ? "\"PRIMARY\"" :
79 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070080 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
81 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080082 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
83 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
84 (mCurrentFrame.needsRedraw? "YES" : "NO"),
85 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070086 if(isDisplaySplit(ctx, mDpy)) {
87 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
88 "Right: [%d, %d, %d, %d] \n",
89 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
90 ctx->listStats[mDpy].lRoi.right,
91 ctx->listStats[mDpy].lRoi.bottom,
92 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
93 ctx->listStats[mDpy].rRoi.right,
94 ctx->listStats[mDpy].rRoi.bottom);
95 } else {
96 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
97 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
98 ctx->listStats[mDpy].lRoi.right,
99 ctx->listStats[mDpy].lRoi.bottom);
100 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800101 dumpsys_log(buf," --------------------------------------------- \n");
102 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
103 dumpsys_log(buf," --------------------------------------------- \n");
104 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
105 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
106 index,
107 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700108 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800109 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700110 (mCurrentFrame.drop[index] ? "DROP" :
111 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800112 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
113 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
114 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115}
116
117bool MDPComp::init(hwc_context_t *ctx) {
118
119 if(!ctx) {
120 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
121 return false;
122 }
123
Saurabh Shah59562ff2014-09-30 16:13:12 -0700124 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800125
126 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530127 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
128 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
130 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800131 sEnabled = true;
132 }
133
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700134 sEnableMixedMode = true;
135 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
136 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
137 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
138 sEnableMixedMode = false;
139 }
140
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700141 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
142
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800143 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700144 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700145 int val = atoi(property);
146 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700147 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800148 }
149
Saurabh Shahacec8e42014-11-25 11:07:04 -0800150 /* Maximum layers allowed to use MDP on secondary panels. If property
151 * doesn't exist, default to 1. Using the property it can be set to 0 or
152 * more.
153 */
154 if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
155 int val = atoi(property);
156 sMaxSecLayers = (val >= 0) ? val : 1;
157 sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
158 }
159
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400160 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700161 sIdleInvalidator = IdleInvalidator::getInstance();
162 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
163 delete sIdleInvalidator;
164 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400165 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800166 }
radhakrishnac9a67412013-09-25 17:40:42 +0530167
Saurabh Shah7c727642014-06-02 15:47:14 -0700168 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700169 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700170 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
171 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
172 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530173 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530174 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700175
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530176 bool defaultPTOR = false;
177 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
178 //8x16 and 8x39 targets by default
179 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
180 (qdutils::MDPVersion::getInstance().is8x16() ||
181 qdutils::MDPVersion::getInstance().is8x39())) {
182 defaultPTOR = true;
183 }
184
185 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
186 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700187 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
188 HWC_DISPLAY_PRIMARY);
189 }
190
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530191 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
192 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
193 enablePartialUpdateForMDP3 = true;
194 }
195
196 if(!enablePartialUpdateForMDP3 &&
197 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
198 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
199 enablePartialUpdateForMDP3 = true;
200 }
201
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -0800202 sIsPartialUpdateActive = getPartialUpdatePref(ctx);
203
Arun Kumar K.R299bcda2014-12-18 19:36:40 -0800204 if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
205 int val = atoi(property);
206 if(val > 0 && loadPerfLib()) {
207 sPerfHintWindow = val;
208 ALOGI("PerfHintWindow = %d", sPerfHintWindow);
209 }
210 }
211
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700212 return true;
213}
214
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800215void MDPComp::reset(hwc_context_t *ctx) {
216 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700217 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800218 ctx->mOverlay->clear(mDpy);
219 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700220}
221
Raj Kamal4393eaa2014-06-06 13:45:20 +0530222void MDPComp::reset() {
223 sHandleTimeout = false;
224 mModeOn = false;
225}
226
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700227void MDPComp::timeout_handler(void *udata) {
228 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
229
230 if(!ctx) {
231 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
232 return;
233 }
Raj Kamal58b31a02014-12-16 15:53:53 +0530234
235 ctx->mDrawLock.lock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800236 // Handle timeout event only if the previous composition is MDP or MIXED.
237 if(!sHandleTimeout) {
238 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530239 ctx->mDrawLock.unlock();
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800240 return;
241 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700242 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700243 ALOGE("%s: HWC proc not registered", __FUNCTION__);
Raj Kamal58b31a02014-12-16 15:53:53 +0530244 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700245 return;
246 }
247 sIdleFallBack = true;
Raj Kamal58b31a02014-12-16 15:53:53 +0530248 ctx->mDrawLock.unlock();
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700249 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700250 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700251}
252
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700253void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
254 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
Saurabh Shah2fd8a252014-12-05 13:49:53 -0800255 uint32_t maxSupported = (int)mdpVersion.getBlendStages();
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700256 if(value > maxSupported) {
257 ALOGW("%s: Input exceeds max value supported. Setting to"
258 "max value: %d", __FUNCTION__, maxSupported);
259 }
260 sMaxPipesPerMixer = min(value, maxSupported);
261}
262
Saurabh Shah59562ff2014-09-30 16:13:12 -0700263void MDPComp::setIdleTimeout(const uint32_t& timeout) {
264 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
265
266 if(sIdleInvalidator) {
267 if(timeout <= ONE_REFRESH_PERIOD_MS) {
268 //If the specified timeout is < 1 draw cycle worth, "virtually"
269 //disable idle timeout. The ideal way for clients to disable
270 //timeout is to set it to 0
271 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
272 ALOGI("Disabled idle timeout");
273 return;
274 }
275 sIdleInvalidator->setIdleTimeout(timeout);
276 ALOGI("Idle timeout set to %u", timeout);
277 } else {
278 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
279 }
280}
281
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800282void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283 hwc_display_contents_1_t* list) {
284 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800285
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800286 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800287 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800288 if(!mCurrentFrame.isFBComposed[index]) {
289 layerProp[index].mFlags |= HWC_MDPCOMP;
290 layer->compositionType = HWC_OVERLAY;
291 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800292 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700293 /* Drop the layer when its already present in FB OR when it lies
294 * outside frame's ROI */
295 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800296 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700297 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800298 }
299 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700300}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500301
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800302void MDPComp::setRedraw(hwc_context_t *ctx,
303 hwc_display_contents_1_t* list) {
304 mCurrentFrame.needsRedraw = false;
305 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
306 (list->flags & HWC_GEOMETRY_CHANGED) ||
307 isSkipPresent(ctx, mDpy)) {
308 mCurrentFrame.needsRedraw = true;
309 }
310}
311
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800312MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700313 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700314 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800315}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800316
Saurabh Shahaa236822013-04-24 18:07:26 -0700317void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700318 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800319 if(mdpToLayer[i].pipeInfo) {
320 delete mdpToLayer[i].pipeInfo;
321 mdpToLayer[i].pipeInfo = NULL;
322 //We dont own the rotator
323 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800324 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800325 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800326
327 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
328 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700329 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330
Saurabh Shahaa236822013-04-24 18:07:26 -0700331 layerCount = numLayers;
332 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800333 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700334 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800335 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336}
337
Saurabh Shahaa236822013-04-24 18:07:26 -0700338void MDPComp::FrameInfo::map() {
339 // populate layer and MDP maps
340 int mdpIdx = 0;
341 for(int idx = 0; idx < layerCount; idx++) {
342 if(!isFBComposed[idx]) {
343 mdpToLayer[mdpIdx].listIndex = idx;
344 layerToMDP[idx] = mdpIdx++;
345 }
346 }
347}
348
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800349MDPComp::LayerCache::LayerCache() {
350 reset();
351}
352
353void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700354 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530355 memset(&isFBComposed, true, sizeof(isFBComposed));
356 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700358}
359
360void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530361 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700362 for(int i = 0; i < numAppLayers; i++) {
363 hnd[i] = list->hwLayers[i].handle;
364 }
365}
366
367void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700368 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530369 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
370 memcpy(&drop, &curFrame.drop, sizeof(drop));
371}
372
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800373bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
374 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530375 if(layerCount != curFrame.layerCount)
376 return false;
377 for(int i = 0; i < curFrame.layerCount; i++) {
378 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
379 (curFrame.drop[i] != drop[i])) {
380 return false;
381 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800382 if(curFrame.isFBComposed[i] &&
383 (hnd[i] != list->hwLayers[i].handle)){
384 return false;
385 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530386 }
387 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800388}
389
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700390bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
391 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800392 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Raj Kamal1179d9c2014-10-28 15:31:35 +0530393 (not isValidDimension(ctx,layer)) ||
394 isSkipLayer(layer)) {
395 //More conditions here, sRGB+Blend etc
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700396 return false;
397 }
398 return true;
399}
400
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530401bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800402 private_handle_t *hnd = (private_handle_t *)layer->handle;
403
404 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700405 if (layer->flags & HWC_COLOR_FILL) {
406 // Color layer
407 return true;
408 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700409 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800410 return false;
411 }
412
Naseer Ahmede850a802013-09-06 13:12:52 -0400413 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400414 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400415 return false;
416
Saurabh Shah62e1d732013-09-17 10:44:05 -0700417 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700418 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700419 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700420 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
421 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700422 int dst_w = dst.right - dst.left;
423 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800424 float w_scale = ((float)crop_w / (float)dst_w);
425 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530426 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700427
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800428 /* Workaround for MDP HW limitation in DSI command mode panels where
429 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
430 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530431 * There also is a HW limilation in MDP, minimum block size is 2x2
432 * Fallback to GPU if height is less than 2.
433 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700434 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800435 return false;
436
Ramkumar Radhakrishnan1a763e92015-03-19 16:46:46 -0700437 /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
438 * those cases
439 */
440 if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
441 return false;
442 }
443
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800444 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530445 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800446 const float w_dscale = w_scale;
447 const float h_dscale = h_scale;
448
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800449 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700450
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530451 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700452 /* On targets that doesnt support Decimation (eg.,8x26)
453 * maximum downscale support is overlay pipe downscale.
454 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800455 if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530456 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700457 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800458 return false;
459 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700460 // Decimation on macrotile format layers is not supported.
461 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530462 /* Bail out if
463 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700464 * 2. exceeds maximum downscale limit
465 */
Jeykumar Sankaran39305802014-12-12 17:55:57 -0800466 if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530467 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700468 w_dscale > maxMDPDownscale ||
469 h_dscale > maxMDPDownscale) {
470 return false;
471 }
472 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800473 return false;
474 }
475 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700476 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700477 return false;
478 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700479 }
480
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800481 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530482 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800483 const float w_uscale = 1.0f / w_scale;
484 const float h_uscale = 1.0f / h_scale;
485
486 if(w_uscale > upscale || h_uscale > upscale)
487 return false;
488 }
489
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800490 return true;
491}
492
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800493bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700494 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800495
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800496 if(!isEnabled()) {
497 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700498 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530499 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530500 qdutils::MDPVersion::getInstance().is8x16() ||
501 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800502 ctx->mVideoTransFlag &&
503 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700504 //1 Padding round to shift pipes across mixers
505 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
506 __FUNCTION__);
507 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700508 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
509 /* TODO: freeing up all the resources only for the targets having total
510 number of pipes < 8. Need to analyze number of VIG pipes used
511 for primary in previous draw cycle and accordingly decide
512 whether to fall back to full GPU comp or video only comp
513 */
514 if(isSecondaryConfiguring(ctx)) {
515 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
516 __FUNCTION__);
517 ret = false;
518 } else if(ctx->isPaddingRound) {
519 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
520 __FUNCTION__,mDpy);
521 ret = false;
522 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800523 } else if (ctx->isDMAStateChanging) {
524 // Bail out if a padding round has been invoked in order to switch DMA
525 // state to block mode. We need this to cater for the case when a layer
526 // requires rotation in the current frame.
527 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
528 __FUNCTION__);
529 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700530 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800531
Saurabh Shahaa236822013-04-24 18:07:26 -0700532 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800533}
534
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800535void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
536 hwc_rect &dst) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800537 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800538 dst = getIntersection(dst, roi);
539 crop = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800540}
541
542/* 1) Identify layers that are not visible or lying outside the updating ROI and
543 * drop them from composition.
544 * 2) If we have a scaling layer which needs cropping against generated
545 * ROI, reset ROI to full resolution. */
546bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
547 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700548 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800549 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800550
551 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800552 if(!isValidRect(visibleRect)) {
553 mCurrentFrame.drop[i] = true;
554 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800555 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800556 }
557
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700558 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700559 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800560 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700561
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700562 if(!isValidRect(res)) {
563 mCurrentFrame.drop[i] = true;
564 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800565 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700566 /* Reset frame ROI when any layer which needs scaling also needs ROI
567 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800568 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800569 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700570 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
571 mCurrentFrame.dropCount = 0;
572 return false;
573 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800574
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800575 /* deduct any opaque region from visibleRect */
radhakrishna4efbdd62014-11-03 13:19:27 +0530576 if (layer->blending == HWC_BLENDING_NONE &&
577 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800578 visibleRect = deductRect(visibleRect, res);
579 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700580 }
581 return true;
582}
583
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800584/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
585 * are updating. If DirtyRegion is applicable, calculate it by accounting all
586 * the changing layer's dirtyRegion. */
587void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
588 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700589 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800590 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700591 return;
592
593 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800594 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
595 (int)ctx->dpyAttr[mDpy].yres};
596
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700597 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800598 hwc_layer_1_t* layer = &list->hwLayers[index];
599 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800600 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700601 hwc_rect_t dst = layer->displayFrame;
602 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800603
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800604#ifdef QCOM_BSP
Dileep Kumar Reddi7399d5c2014-12-31 18:01:19 +0530605 if(!needsScaling(layer) && !layer->transform &&
606 (!isYuvBuffer((private_handle_t *)layer->handle)))
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700607 {
608 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
609 int x_off = dst.left - src.left;
610 int y_off = dst.top - src.top;
611 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
612 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800613#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800614
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800615 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700616 }
617 }
618
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800619 /* No layer is updating. Still SF wants a refresh.*/
620 if(!isValidRect(roi))
621 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800622
623 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800624 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800625
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800626 ctx->listStats[mDpy].lRoi = roi;
627 if(!validateAndApplyROI(ctx, list))
628 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700629
630 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800631 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
632 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
633}
634
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800635void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
636 hwc_rect &dst) {
637 hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
638 ctx->listStats[mDpy].rRoi);
639 hwc_rect tmpDst = getIntersection(dst, roi);
640 if(!isSameRect(dst, tmpDst)) {
641 crop.left = crop.left + (tmpDst.left - dst.left);
642 crop.top = crop.top + (tmpDst.top - dst.top);
643 crop.right = crop.left + (tmpDst.right - tmpDst.left);
644 crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
645 dst = tmpDst;
646 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800647}
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -0800648
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800649/* 1) Identify layers that are not visible or lying outside BOTH the updating
650 * ROI's and drop them from composition. If a layer is spanning across both
651 * the halves of the screen but needed by only ROI, the non-contributing
652 * half will not be programmed for MDP.
653 * 2) If we have a scaling layer which needs cropping against generated
654 * ROI, reset ROI to full resolution. */
655bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
656 hwc_display_contents_1_t* list) {
657
658 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
659
660 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
661 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
662
663 for(int i = numAppLayers - 1; i >= 0; i--){
664 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
665 {
666 mCurrentFrame.drop[i] = true;
667 mCurrentFrame.dropCount++;
668 continue;
669 }
670
671 const hwc_layer_1_t* layer = &list->hwLayers[i];
672 hwc_rect_t dstRect = layer->displayFrame;
673
674 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
675 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
676 hwc_rect_t res = getUnion(l_res, r_res);
677
678 if(!isValidRect(l_res) && !isValidRect(r_res)) {
679 mCurrentFrame.drop[i] = true;
680 mCurrentFrame.dropCount++;
681 } else {
682 /* Reset frame ROI when any layer which needs scaling also needs ROI
683 * cropping */
684 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
685 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
686 mCurrentFrame.dropCount = 0;
687 return false;
688 }
689
radhakrishna4efbdd62014-11-03 13:19:27 +0530690 if (layer->blending == HWC_BLENDING_NONE &&
691 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800692 visibleRectL = deductRect(visibleRectL, l_res);
693 visibleRectR = deductRect(visibleRectR, r_res);
694 }
695 }
696 }
697 return true;
698}
699/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
700 * are updating. If DirtyRegion is applicable, calculate it by accounting all
701 * the changing layer's dirtyRegion. */
702void MDPCompSplit::generateROI(hwc_context_t *ctx,
703 hwc_display_contents_1_t* list) {
704 if(!canPartialUpdate(ctx, list))
705 return;
706
707 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
708 int lSplit = getLeftSplit(ctx, mDpy);
709
710 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
711 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
712
713 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
714 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
715
716 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
717 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
718
719 for(int index = 0; index < numAppLayers; index++ ) {
720 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800721 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800722 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800723 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700724 hwc_rect_t dst = layer->displayFrame;
725 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800726
727#ifdef QCOM_BSP
728 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700729 {
730 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
731 int x_off = dst.left - src.left;
732 int y_off = dst.top - src.top;
733 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
734 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800735#endif
736
737 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
738 if(isValidRect(l_dst))
739 l_roi = getUnion(l_roi, l_dst);
740
741 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
742 if(isValidRect(r_dst))
743 r_roi = getUnion(r_roi, r_dst);
744 }
745 }
746
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700747 /* For panels that cannot accept commands in both the interfaces, we cannot
748 * send two ROI's (for each half). We merge them into single ROI and split
749 * them across lSplit for MDP mixer use. The ROI's will be merged again
750 * finally before udpating the panel in the driver. */
751 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
752 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
753 l_roi = getIntersection(temp_roi, l_frame);
754 r_roi = getIntersection(temp_roi, r_frame);
755 }
756
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800757 /* No layer is updating. Still SF wants a refresh. */
758 if(!isValidRect(l_roi) && !isValidRect(r_roi))
759 return;
760
761 l_roi = getSanitizeROI(l_roi, l_frame);
762 r_roi = getSanitizeROI(r_roi, r_frame);
763
764 ctx->listStats[mDpy].lRoi = l_roi;
765 ctx->listStats[mDpy].rRoi = r_roi;
766
767 if(!validateAndApplyROI(ctx, list))
768 resetROI(ctx, mDpy);
769
770 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
771 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
772 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
773 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
774 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
775 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700776}
777
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800778/* Checks for conditions where all the layers marked for MDP comp cannot be
779 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800780bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800781 hwc_display_contents_1_t* list){
782
Saurabh Shahaa236822013-04-24 18:07:26 -0700783 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800784
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700785 // Fall back to video only composition, if AIV video mode is enabled
786 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700787 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
788 __FUNCTION__, mDpy);
789 return false;
790 }
791
Praveena Pachipulusu47346c22014-12-04 11:06:41 +0530792 /* No Idle fall back if secure display or secure RGB layers are present
793 * or if there is only a single layer being composed */
794 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
795 !ctx->listStats[mDpy].secureRGBCount &&
796 (ctx->listStats[mDpy].numAppLayers > 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700797 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
798 return false;
799 }
800
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700801 // if secondary is configuring or Padding round, fall back to video only
802 // composition and release all assigned non VIG pipes from primary.
803 if(isSecondaryConfiguring(ctx)) {
804 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
805 __FUNCTION__);
806 return false;
807 } else if(ctx->isPaddingRound) {
808 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
809 __FUNCTION__,mDpy);
810 return false;
811 }
812
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -0500813 // No MDP composition for 3D
814 if(needs3DComposition(ctx, mDpy))
815 return false;
816
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700817 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800818 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700819 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800820 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
821 return false;
822 }
823
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800824 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800825 hwc_layer_1_t* layer = &list->hwLayers[i];
826 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800827
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800828 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700829 if(!canUseRotator(ctx, mDpy)) {
830 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
831 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700832 return false;
833 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800834 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530835
836 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
837 // may not need it if Gfx pre-rotation can handle all flips & rotations
Saurabh Shahcad57772014-12-01 14:19:51 -0800838 MDPVersion& mdpHw = MDPVersion::getInstance();
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700839 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530840 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
841 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
842 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800843 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700844
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700845 if(ctx->mAD->isDoable()) {
846 return false;
847 }
848
Saurabh Shahaa236822013-04-24 18:07:26 -0700849 //If all above hard conditions are met we can do full or partial MDP comp.
850 bool ret = false;
851 if(fullMDPComp(ctx, list)) {
852 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700853 } else if(fullMDPCompWithPTOR(ctx, list)) {
854 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700855 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700856 ret = true;
857 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530858
Saurabh Shahaa236822013-04-24 18:07:26 -0700859 return ret;
860}
861
862bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700863
864 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
865 return false;
866
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700867 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
868 for(int i = 0; i < numAppLayers; i++) {
869 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700870 if(not mCurrentFrame.drop[i] and
871 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700872 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
873 return false;
874 }
875 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800876
Saurabh Shahaa236822013-04-24 18:07:26 -0700877 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700878 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
879 sizeof(mCurrentFrame.isFBComposed));
880 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
881 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700882
Raj Kamal389d6e32014-08-04 14:43:24 +0530883 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800884 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530885 }
886
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800887 if(!postHeuristicsHandling(ctx, list)) {
888 ALOGD_IF(isDebug(), "post heuristic handling failed");
889 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700890 return false;
891 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700892 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
893 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700894 return true;
895}
896
Sushil Chauhandefd3522014-05-13 18:17:12 -0700897/* Full MDP Composition with Peripheral Tiny Overlap Removal.
898 * MDP bandwidth limitations can be avoided, if the overlap region
899 * covered by the smallest layer at a higher z-order, gets composed
900 * by Copybit on a render buffer, which can be queued to MDP.
901 */
902bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
903 hwc_display_contents_1_t* list) {
904
905 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
906 const int stagesForMDP = min(sMaxPipesPerMixer,
907 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
908
909 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700910 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
912 return false;
913 }
914
915 // Frame level checks
916 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
917 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
918 isSecurePresent(ctx, mDpy)) {
919 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
920 return false;
921 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700922 // MDP comp checks
923 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700924 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700925 if(not isSupportedForMDPComp(ctx, layer)) {
926 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
927 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700928 }
929 }
930
Sushil Chauhandefd3522014-05-13 18:17:12 -0700931 /* We cannot use this composition mode, if:
932 1. A below layer needs scaling.
933 2. Overlap is not peripheral to display.
934 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700935 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700936 */
937
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
939 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
940 memset(overlapRect, 0, sizeof(overlapRect));
941 int layerPixelCount, minPixelCount = 0;
942 int numPTORLayersFound = 0;
943 for (int i = numAppLayers-1; (i >= 0 &&
944 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700945 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700946 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700947 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700948 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
949 // PTOR layer should be peripheral and cannot have transform
950 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
951 has90Transform(layer)) {
952 continue;
953 }
954 if((3 * (layerPixelCount + minPixelCount)) >
955 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
956 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
957 continue;
958 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700959 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700960 for (int j = i-1; j >= 0; j--) {
961 // Check if the layers below this layer qualifies for PTOR comp
962 hwc_layer_1_t* layer = &list->hwLayers[j];
963 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700964 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700965 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700966 if (isValidRect(getIntersection(dispFrame, disFrame))) {
967 if (has90Transform(layer) || needsScaling(layer)) {
968 found = false;
969 break;
970 }
971 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700972 }
973 }
974 // Store the minLayer Index
975 if(found) {
976 minLayerIndex[numPTORLayersFound] = i;
977 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
978 minPixelCount += layerPixelCount;
979 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700980 }
981 }
982
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700983 // No overlap layers
984 if (!numPTORLayersFound)
985 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700986
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700987 // Store the displayFrame and the sourceCrops of the layers
988 hwc_rect_t displayFrame[numAppLayers];
989 hwc_rect_t sourceCrop[numAppLayers];
990 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700991 hwc_layer_1_t* layer = &list->hwLayers[i];
992 displayFrame[i] = layer->displayFrame;
993 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700994 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700995
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530996 /**
997 * It's possible that 2 PTOR layers might have overlapping.
998 * In such case, remove the intersection(again if peripheral)
999 * from the lower PTOR layer to avoid overlapping.
1000 * If intersection is not on peripheral then compromise
1001 * by reducing number of PTOR layers.
1002 **/
1003 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1004 if(isValidRect(commonRect)) {
1005 overlapRect[1] = deductRect(overlapRect[1], commonRect);
1006 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1007 }
1008
1009 ctx->mPtorInfo.count = numPTORLayersFound;
1010 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1011 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1012 }
1013
1014 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1015 // reset PTOR
1016 ctx->mPtorInfo.count = 0;
1017 if(isValidRect(commonRect)) {
1018 // If PTORs are intersecting restore displayframe of PTOR[1]
1019 // before returning, as we have modified it above.
1020 list->hwLayers[minLayerIndex[1]].displayFrame =
1021 displayFrame[minLayerIndex[1]];
1022 }
1023 return false;
1024 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001025 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1026 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1027
Xu Yangcda012c2014-07-30 21:57:21 +08001028 // Store the blending mode, planeAlpha, and transform of PTOR layers
1029 int32_t blending[numPTORLayersFound];
1030 uint8_t planeAlpha[numPTORLayersFound];
1031 uint32_t transform[numPTORLayersFound];
1032
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001033 for(int j = 0; j < numPTORLayersFound; j++) {
1034 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001035
1036 // Update src crop of PTOR layer
1037 hwc_layer_1_t* layer = &list->hwLayers[index];
1038 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1039 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1040 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1041 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1042
1043 // Store & update w, h, format of PTOR layer
1044 private_handle_t *hnd = (private_handle_t *)layer->handle;
1045 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1046 layerWhf[j] = whf;
1047 hnd->width = renderBuf->width;
1048 hnd->height = renderBuf->height;
1049 hnd->format = renderBuf->format;
1050
Xu Yangcda012c2014-07-30 21:57:21 +08001051 // Store & update blending mode, planeAlpha and transform of PTOR layer
1052 blending[j] = layer->blending;
1053 planeAlpha[j] = layer->planeAlpha;
1054 transform[j] = layer->transform;
1055 layer->blending = HWC_BLENDING_NONE;
1056 layer->planeAlpha = 0xFF;
1057 layer->transform = 0;
1058
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001059 // Remove overlap from crop & displayFrame of below layers
1060 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001061 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001062 if(!isValidRect(getIntersection(layer->displayFrame,
1063 overlapRect[j]))) {
1064 continue;
1065 }
1066 // Update layer attributes
1067 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1068 hwc_rect_t destRect = deductRect(layer->displayFrame,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301069 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001070 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1071 layer->transform);
1072 layer->sourceCropf.left = (float)srcCrop.left;
1073 layer->sourceCropf.top = (float)srcCrop.top;
1074 layer->sourceCropf.right = (float)srcCrop.right;
1075 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1076 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001077 }
1078
1079 mCurrentFrame.mdpCount = numAppLayers;
1080 mCurrentFrame.fbCount = 0;
1081 mCurrentFrame.fbZ = -1;
1082
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301083 for (int j = 0; j < numAppLayers; j++) {
1084 if(isValidRect(list->hwLayers[j].displayFrame)) {
1085 mCurrentFrame.isFBComposed[j] = false;
1086 } else {
1087 mCurrentFrame.mdpCount--;
1088 mCurrentFrame.drop[j] = true;
1089 }
1090 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001091
1092 bool result = postHeuristicsHandling(ctx, list);
1093
1094 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001095 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001096 hwc_layer_1_t* layer = &list->hwLayers[i];
1097 layer->displayFrame = displayFrame[i];
1098 layer->sourceCropf.left = (float)sourceCrop[i].left;
1099 layer->sourceCropf.top = (float)sourceCrop[i].top;
1100 layer->sourceCropf.right = (float)sourceCrop[i].right;
1101 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1102 }
1103
Xu Yangcda012c2014-07-30 21:57:21 +08001104 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001105 for (int i = 0; i < numPTORLayersFound; i++) {
1106 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001107 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001108 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1109 hnd->width = layerWhf[i].w;
1110 hnd->height = layerWhf[i].h;
1111 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001112 layer->blending = blending[i];
1113 layer->planeAlpha = planeAlpha[i];
1114 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001115 }
1116
Sushil Chauhandefd3522014-05-13 18:17:12 -07001117 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001118 // reset PTOR
1119 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001120 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001121 } else {
1122 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1123 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001124 }
1125
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001126 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1127 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001128 return result;
1129}
1130
Saurabh Shahaa236822013-04-24 18:07:26 -07001131bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1132{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001133 if(!sEnableMixedMode) {
1134 //Mixed mode is disabled. No need to even try caching.
1135 return false;
1136 }
1137
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001138 bool ret = false;
Raj Kamal1179d9c2014-10-28 15:31:35 +05301139 if(isSkipPresent(ctx, mDpy) or list->flags & HWC_GEOMETRY_CHANGED) {
1140 //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001141 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001142 cacheBasedComp(ctx, list);
1143 } else {
1144 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001145 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001146 }
1147
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001148 return ret;
1149}
1150
1151bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1152 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001153 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1154 return false;
1155
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001156 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001157 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001158 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001159
1160 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1161 for(int i = 0; i < numAppLayers; i++) {
1162 if(!mCurrentFrame.isFBComposed[i]) {
1163 hwc_layer_1_t* layer = &list->hwLayers[i];
1164 if(not isSupportedForMDPComp(ctx, layer)) {
1165 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1166 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001167 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001168 return false;
1169 }
1170 }
1171 }
1172
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001173 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001174 /* mark secure RGB layers for MDP comp */
1175 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301176 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001177 if(!ret) {
1178 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001179 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001180 return false;
1181 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001182
1183 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001184
Raj Kamal389d6e32014-08-04 14:43:24 +05301185 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001186 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301187 }
1188
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001189 if(!postHeuristicsHandling(ctx, list)) {
1190 ALOGD_IF(isDebug(), "post heuristic handling failed");
1191 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001192 return false;
1193 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001194 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1195 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001196
Saurabh Shahaa236822013-04-24 18:07:26 -07001197 return true;
1198}
1199
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001200bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001201 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001202 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1203 return false;
1204
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001205 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001206 return false;
1207 }
1208
Saurabh Shahb772ae32013-11-18 15:40:02 -08001209 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001210 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1211 const int stagesForMDP = min(sMaxPipesPerMixer,
1212 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001213
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001214 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1215 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1216 int lastMDPSupportedIndex = numAppLayers;
1217 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001218
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001219 //Find the minimum MDP batch size
1220 for(int i = 0; i < numAppLayers;i++) {
1221 if(mCurrentFrame.drop[i]) {
1222 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001223 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001224 }
1225 hwc_layer_1_t* layer = &list->hwLayers[i];
1226 if(not isSupportedForMDPComp(ctx, layer)) {
1227 lastMDPSupportedIndex = i;
1228 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1229 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001230 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001231 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001232 }
1233
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001234 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1235 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1236 mCurrentFrame.dropCount);
1237
1238 //Start at a point where the fb batch should at least have 2 layers, for
1239 //this mode to be justified.
1240 while(fbBatchSize < 2) {
1241 ++fbBatchSize;
1242 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001243 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001244
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001245 //If there are no layers for MDP, this mode doesnt make sense.
1246 if(mdpBatchSize < 1) {
1247 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1248 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001249 return false;
1250 }
1251
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001252 mCurrentFrame.reset(numAppLayers);
1253
1254 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1255 while(mdpBatchSize > 0) {
1256 //Mark layers for MDP comp
1257 int mdpBatchLeft = mdpBatchSize;
1258 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1259 if(mCurrentFrame.drop[i]) {
1260 continue;
1261 }
1262 mCurrentFrame.isFBComposed[i] = false;
1263 --mdpBatchLeft;
1264 }
1265
1266 mCurrentFrame.fbZ = mdpBatchSize;
1267 mCurrentFrame.fbCount = fbBatchSize;
1268 mCurrentFrame.mdpCount = mdpBatchSize;
1269
1270 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1271 __FUNCTION__, mdpBatchSize, fbBatchSize,
1272 mCurrentFrame.dropCount);
1273
1274 if(postHeuristicsHandling(ctx, list)) {
1275 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001276 __FUNCTION__);
1277 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1278 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001279 return true;
1280 }
1281
1282 reset(ctx);
1283 --mdpBatchSize;
1284 ++fbBatchSize;
1285 }
1286
1287 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001288}
1289
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001290bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301291 if(mDpy or isSecurePresent(ctx, mDpy) or
1292 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001293 return false;
1294 }
1295 return true;
1296}
1297
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001298bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1299 hwc_display_contents_1_t* list){
1300 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1301 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07001302 !sIsPartialUpdateActive || mDpy ) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001303 return false;
1304 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001305 if(ctx->listStats[mDpy].secureUI)
1306 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001307 return true;
1308}
1309
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001310bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1311 hwc_display_contents_1_t* list) {
1312 const bool secureOnly = true;
1313 return videoOnlyComp(ctx, list, not secureOnly) or
1314 videoOnlyComp(ctx, list, secureOnly);
1315}
1316
1317bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001318 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001319 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1320 return false;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301321
Saurabh Shahaa236822013-04-24 18:07:26 -07001322 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301323 if(!isSecurePresent(ctx, mDpy)) {
1324 /* Bail out if we are processing only secured video layers
1325 * and we dont have any */
1326 if(secureOnly) {
1327 ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1328 return false;
1329 }
1330 /* No Idle fall back for secure video layers and if there is only
1331 * single layer being composed. */
1332 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1333 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1334 return false;
1335 }
1336 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001337
Saurabh Shahaa236822013-04-24 18:07:26 -07001338 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001339 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001340 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001341 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001342
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001343 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1344 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001345 return false;
1346 }
1347
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001348 if(mCurrentFrame.fbCount)
1349 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001350
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001351 if(sEnableYUVsplit || needs3DComposition(ctx, mDpy)){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001352 adjustForSourceSplit(ctx, list);
1353 }
1354
1355 if(!postHeuristicsHandling(ctx, list)) {
1356 ALOGD_IF(isDebug(), "post heuristic handling failed");
Justin Philip37ab9a82015-01-06 11:55:12 +05301357 if(errno == ENOBUFS) {
1358 ALOGD_IF(isDebug(), "SMP Allocation failed");
1359 //On SMP allocation failure in video only comp add padding round
1360 ctx->isPaddingRound = true;
1361 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001362 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001363 return false;
1364 }
1365
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001366 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1367 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001368 return true;
1369}
1370
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001371/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1372bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1373 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001374 // Fall back to video only composition, if AIV video mode is enabled
1375 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001376 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1377 __FUNCTION__, mDpy);
1378 return false;
1379 }
1380
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001381 // No MDP composition for 3D
1382 if(needs3DComposition(ctx,mDpy))
1383 return false;
1384
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001385 const bool secureOnly = true;
1386 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1387 mdpOnlyLayersComp(ctx, list, secureOnly);
1388
1389}
1390
1391bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1392 hwc_display_contents_1_t* list, bool secureOnly) {
1393
1394 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1395 return false;
1396
Praveena Pachipulusu47346c22014-12-04 11:06:41 +05301397 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1398 if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1399 /* Bail out if we are processing only secured video/ui layers
1400 * and we dont have any */
1401 if(secureOnly) {
1402 ALOGD_IF(isDebug(), "%s: No secure video/ui layers");
1403 return false;
1404 }
1405 /* No Idle fall back for secure video/ui layers and if there is only
1406 * single layer being composed. */
1407 if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1408 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1409 return false;
1410 }
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001411 }
1412
Tatenda Chipeperekwa95675a72014-12-15 17:06:43 -08001413 /* Bail out if we dont have any secure RGB layers */
1414 if (!ctx->listStats[mDpy].secureRGBCount) {
1415 reset(ctx);
1416 return false;
1417 }
1418
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001419 mCurrentFrame.reset(numAppLayers);
1420 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1421
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001422 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001423 /* mark secure RGB layers for MDP comp */
1424 updateSecureRGB(ctx, list);
1425
1426 if(mCurrentFrame.mdpCount == 0) {
1427 reset(ctx);
1428 return false;
1429 }
1430
1431 /* find the maximum batch of layers to be marked for framebuffer */
1432 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1433 if(!ret) {
1434 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1435 reset(ctx);
1436 return false;
1437 }
1438
1439 if(sEnableYUVsplit){
1440 adjustForSourceSplit(ctx, list);
1441 }
1442
1443 if(!postHeuristicsHandling(ctx, list)) {
1444 ALOGD_IF(isDebug(), "post heuristic handling failed");
1445 reset(ctx);
1446 return false;
1447 }
1448
1449 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1450 __FUNCTION__);
1451 return true;
1452}
1453
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001454/* Checks for conditions where YUV layers cannot be bypassed */
1455bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001456 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001457 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001458 return false;
1459 }
1460
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001461 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001462 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1463 return false;
1464 }
1465
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001466 if(isSecuring(ctx, layer)) {
1467 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1468 return false;
1469 }
1470
Saurabh Shah4fdde762013-04-30 18:47:33 -07001471 if(!isValidDimension(ctx, layer)) {
1472 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1473 __FUNCTION__);
1474 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001475 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001476
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001477 if(layer->planeAlpha < 0xFF) {
1478 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1479 in video only mode",
1480 __FUNCTION__);
1481 return false;
1482 }
1483
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001484 return true;
1485}
1486
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001487/* Checks for conditions where Secure RGB layers cannot be bypassed */
1488bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1489 if(isSkipLayer(layer)) {
1490 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1491 __FUNCTION__, mDpy);
1492 return false;
1493 }
1494
1495 if(isSecuring(ctx, layer)) {
1496 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1497 return false;
1498 }
1499
1500 if(not isSupportedForMDPComp(ctx, layer)) {
1501 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1502 __FUNCTION__);
1503 return false;
1504 }
1505 return true;
1506}
1507
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301508/* starts at fromIndex and check for each layer to find
1509 * if it it has overlapping with any Updating layer above it in zorder
1510 * till the end of the batch. returns true if it finds any intersection */
1511bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1512 int fromIndex, int toIndex) {
1513 for(int i = fromIndex; i < toIndex; i++) {
1514 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1515 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1516 return false;
1517 }
1518 }
1519 }
1520 return true;
1521}
1522
1523/* Checks if given layer at targetLayerIndex has any
1524 * intersection with all the updating layers in beween
1525 * fromIndex and toIndex. Returns true if it finds intersectiion */
1526bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1527 int fromIndex, int toIndex, int targetLayerIndex) {
1528 for(int i = fromIndex; i <= toIndex; i++) {
1529 if(!mCurrentFrame.isFBComposed[i]) {
1530 if(areLayersIntersecting(&list->hwLayers[i],
1531 &list->hwLayers[targetLayerIndex])) {
1532 return true;
1533 }
1534 }
1535 }
1536 return false;
1537}
1538
1539int MDPComp::getBatch(hwc_display_contents_1_t* list,
1540 int& maxBatchStart, int& maxBatchEnd,
1541 int& maxBatchCount) {
1542 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301543 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001544 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301545 while (i < mCurrentFrame.layerCount) {
1546 int batchCount = 0;
1547 int batchStart = i;
1548 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001549 /* Adjust batch Z order with the dropped layers so far */
1550 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301551 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301552 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301553 while(i < mCurrentFrame.layerCount) {
1554 if(!mCurrentFrame.isFBComposed[i]) {
1555 if(!batchCount) {
1556 i++;
1557 break;
1558 }
1559 updatingLayersAbove++;
1560 i++;
1561 continue;
1562 } else {
1563 if(mCurrentFrame.drop[i]) {
1564 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001565 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301566 continue;
1567 } else if(updatingLayersAbove <= 0) {
1568 batchCount++;
1569 batchEnd = i;
1570 i++;
1571 continue;
1572 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1573
1574 // We have a valid updating layer already. If layer-i not
1575 // have overlapping with all updating layers in between
1576 // batch-start and i, then we can add layer i to batch.
1577 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1578 batchCount++;
1579 batchEnd = i;
1580 i++;
1581 continue;
1582 } else if(canPushBatchToTop(list, batchStart, i)) {
1583 //If All the non-updating layers with in this batch
1584 //does not have intersection with the updating layers
1585 //above in z-order, then we can safely move the batch to
1586 //higher z-order. Increment fbZ as it is moving up.
1587 if( firstZReverseIndex < 0) {
1588 firstZReverseIndex = i;
1589 }
1590 batchCount++;
1591 batchEnd = i;
1592 fbZ += updatingLayersAbove;
1593 i++;
1594 updatingLayersAbove = 0;
1595 continue;
1596 } else {
1597 //both failed.start the loop again from here.
1598 if(firstZReverseIndex >= 0) {
1599 i = firstZReverseIndex;
1600 }
1601 break;
1602 }
1603 }
1604 }
1605 }
1606 if(batchCount > maxBatchCount) {
1607 maxBatchCount = batchCount;
1608 maxBatchStart = batchStart;
1609 maxBatchEnd = batchEnd;
1610 fbZOrder = fbZ;
1611 }
1612 }
1613 return fbZOrder;
1614}
1615
1616bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1617 hwc_display_contents_1_t* list) {
1618 /* Idea is to keep as many non-updating(cached) layers in FB and
1619 * send rest of them through MDP. This is done in 2 steps.
1620 * 1. Find the maximum contiguous batch of non-updating layers.
1621 * 2. See if we can improve this batch size for caching by adding
1622 * opaque layers around the batch, if they don't have
1623 * any overlapping with the updating layers in between.
1624 * NEVER mark an updating layer for caching.
1625 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001626
1627 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001628 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001629 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301630 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001631
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001632 /* Nothing is cached. No batching needed */
1633 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001634 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001635 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001636
1637 /* No MDP comp layers, try to use other comp modes */
1638 if(mCurrentFrame.mdpCount == 0) {
1639 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001640 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001641
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301642 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001643
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301644 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001645 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001646 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001647 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301648 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001649 if(!mCurrentFrame.drop[i]){
1650 //If an unsupported layer is being attempted to
1651 //be pulled out we should fail
1652 if(not isSupportedForMDPComp(ctx, layer)) {
1653 return false;
1654 }
1655 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001656 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001657 }
1658 }
1659
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301660 // update the frame data
1661 mCurrentFrame.fbZ = fbZ;
1662 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001663 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001664 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001665
1666 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301667 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001668
1669 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001670}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001671
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001672void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001673 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001674 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001675 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001676
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001677 for(int i = 0; i < numAppLayers; i++) {
1678 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001679 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001680 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001681 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001682 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001683 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001684 }
1685 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001686
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001687 frame.fbCount = fbCount;
1688 frame.mdpCount = frame.layerCount - frame.fbCount
1689 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001690
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001691 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1692 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693}
1694
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001695// drop other non-AIV layers from external display list.
1696void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001697 hwc_display_contents_1_t* list) {
1698 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1699 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001700 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001701 mCurrentFrame.dropCount++;
1702 mCurrentFrame.drop[i] = true;
1703 }
1704 }
1705 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1706 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1707 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1708 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1709 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1710 mCurrentFrame.dropCount);
1711}
1712
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001713void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001714 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001715 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1716 for(int index = 0;index < nYuvCount; index++){
1717 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1718 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1719
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001720 if(mCurrentFrame.drop[nYuvIndex]) {
1721 continue;
1722 }
1723
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001724 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001725 if(!frame.isFBComposed[nYuvIndex]) {
1726 frame.isFBComposed[nYuvIndex] = true;
1727 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001728 }
1729 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001730 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001731 private_handle_t *hnd = (private_handle_t *)layer->handle;
1732 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001733 frame.isFBComposed[nYuvIndex] = false;
1734 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001735 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001736 }
1737 }
1738 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001739
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001740 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1741 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001742}
1743
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001744void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1745 hwc_display_contents_1_t* list) {
1746 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1747 for(int index = 0;index < nSecureRGBCount; index++){
1748 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1749 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1750
1751 if(!isSecureRGBDoable(ctx, layer)) {
1752 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1753 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1754 mCurrentFrame.fbCount++;
1755 }
1756 } else {
1757 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1758 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1759 mCurrentFrame.fbCount--;
1760 }
1761 }
1762 }
1763
1764 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1765 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1766 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1767 mCurrentFrame.fbCount);
1768}
1769
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001770hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1771 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001772 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001773
1774 /* Update only the region of FB needed for composition */
1775 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1776 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1777 hwc_layer_1_t* layer = &list->hwLayers[i];
1778 hwc_rect_t dst = layer->displayFrame;
1779 fbRect = getUnion(fbRect, dst);
1780 }
1781 }
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08001782 trimAgainstROI(ctx, fbRect, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001783 return fbRect;
1784}
1785
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001786bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1787 hwc_display_contents_1_t* list) {
1788
1789 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001790 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001791 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1792 return false;
1793 }
1794
1795 //Limitations checks
1796 if(!hwLimitationsCheck(ctx, list)) {
1797 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1798 return false;
1799 }
1800
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001801 //Configure framebuffer first if applicable
1802 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001803 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001804 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1805 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001806 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1807 __FUNCTION__);
1808 return false;
1809 }
1810 }
1811
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001812 mCurrentFrame.map();
1813
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814 if(!allocLayerPipes(ctx, list)) {
1815 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001816 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001817 }
1818
1819 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001820 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001821 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001822 int mdpIndex = mCurrentFrame.layerToMDP[index];
1823 hwc_layer_1_t* layer = &list->hwLayers[index];
1824
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301825 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1826 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1827 mdpNextZOrder++;
1828 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001829 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1830 cur_pipe->zOrder = mdpNextZOrder++;
1831
radhakrishnac9a67412013-09-25 17:40:42 +05301832 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301833 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301834 if(configure4k2kYuv(ctx, layer,
1835 mCurrentFrame.mdpToLayer[mdpIndex])
1836 != 0 ){
1837 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1838 for layer %d",__FUNCTION__, index);
1839 return false;
1840 }
1841 else{
1842 mdpNextZOrder++;
1843 }
1844 continue;
1845 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05001846 if(needs3DComposition(ctx,mDpy) && get3DFormat(hnd) != HAL_NO_3D) {
1847 mdpNextZOrder++;
1848 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001849 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1850 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301851 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001852 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001853 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001854 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001855 }
1856
Saurabh Shaha36be922013-12-16 18:18:39 -08001857 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1858 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1859 ,__FUNCTION__, mDpy);
1860 return false;
1861 }
1862
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001863 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001864 return true;
1865}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001866
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001867bool MDPComp::resourceCheck(hwc_context_t* ctx,
1868 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001869 const bool fbUsed = mCurrentFrame.fbCount;
1870 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1871 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1872 return false;
1873 }
Saurabh Shahacec8e42014-11-25 11:07:04 -08001874
1875 //Will benefit cases where a video has non-updating background.
1876 if((mDpy > HWC_DISPLAY_PRIMARY) and
1877 (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1878 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1879 return false;
1880 }
1881
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001882 // Init rotCount to number of rotate sessions used by other displays
1883 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1884 // Count the number of rotator sessions required for current display
1885 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1886 if(!mCurrentFrame.isFBComposed[index]) {
1887 hwc_layer_1_t* layer = &list->hwLayers[index];
1888 private_handle_t *hnd = (private_handle_t *)layer->handle;
1889 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1890 rotCount++;
1891 }
1892 }
1893 }
1894 // if number of layers to rotate exceeds max rotator sessions, bail out.
1895 if(rotCount > RotMgr::MAX_ROT_SESS) {
1896 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1897 __FUNCTION__, mDpy);
1898 return false;
1899 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001900 return true;
1901}
1902
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301903bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1904 hwc_display_contents_1_t* list) {
1905
1906 //A-family hw limitation:
1907 //If a layer need alpha scaling, MDP can not support.
1908 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1909 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1910 if(!mCurrentFrame.isFBComposed[i] &&
1911 isAlphaScaled( &list->hwLayers[i])) {
1912 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1913 return false;
1914 }
1915 }
1916 }
1917
1918 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1919 //If multiple layers requires downscaling and also they are overlapping
1920 //fall back to GPU since MDSS can not handle it.
1921 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1922 qdutils::MDPVersion::getInstance().is8x26()) {
1923 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1924 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1925 if(!mCurrentFrame.isFBComposed[i] &&
1926 isDownscaleRequired(botLayer)) {
1927 //if layer-i is marked for MDP and needs downscaling
1928 //check if any MDP layer on top of i & overlaps with layer-i
1929 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1930 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1931 if(!mCurrentFrame.isFBComposed[j] &&
1932 isDownscaleRequired(topLayer)) {
1933 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1934 topLayer->displayFrame);
1935 if(isValidRect(r))
1936 return false;
1937 }
1938 }
1939 }
1940 }
1941 }
1942 return true;
1943}
1944
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001945// Checks only if videos or single layer(RGB) is updating
1946// which is used for setting dynamic fps or perf hint for single
1947// layer video playback
1948bool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1949 hwc_display_contents_1_t* list) {
1950 bool support = false;
1951 FrameInfo frame;
1952 frame.reset(mCurrentFrame.layerCount);
1953 memset(&frame.drop, 0, sizeof(frame.drop));
1954 frame.dropCount = 0;
1955 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1956 updateLayerCache(ctx, list, frame);
1957 updateYUV(ctx, list, false /*secure only*/, frame);
1958 // There are only updating YUV layers or there is single RGB
1959 // Layer(Youtube)
1960 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1961 (frame.layerCount == 1)) {
1962 support = true;
1963 }
1964 return support;
1965}
1966
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301967void MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1968 //For primary display, set the dynamic refreshrate
1969 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1970 ctx->mUseMetaDataRefreshRate) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301971 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1972 MDPVersion& mdpHw = MDPVersion::getInstance();
1973 if(sIdleFallBack) {
1974 //Set minimum panel refresh rate during idle timeout
1975 refreshRate = mdpHw.getMinFpsSupported();
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08001976 } else if(onlyVideosUpdating(ctx, list)) {
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05301977 //Set the new fresh rate, if there is only one updating YUV layer
1978 //or there is one single RGB layer with this request
1979 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1980 }
1981 setRefreshRate(ctx, mDpy, refreshRate);
1982 }
1983}
1984
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001985int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001986 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001987 char property[PROPERTY_VALUE_MAX];
1988
Raj Kamal4393eaa2014-06-06 13:45:20 +05301989 if(!ctx || !list) {
1990 ALOGE("%s: Invalid context or list",__FUNCTION__);
1991 mCachedFrame.reset();
1992 return -1;
1993 }
1994
1995 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001996 if(mDpy == HWC_DISPLAY_PRIMARY) {
1997 sSimulationFlags = 0;
1998 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1999 int currentFlags = atoi(property);
2000 if(currentFlags != sSimulationFlags) {
2001 sSimulationFlags = currentFlags;
2002 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2003 sSimulationFlags, sSimulationFlags);
2004 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07002005 }
2006 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002007 // reset PTOR
2008 if(!mDpy)
2009 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07002010
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302011 //reset old data
2012 mCurrentFrame.reset(numLayers);
2013 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2014 mCurrentFrame.dropCount = 0;
2015
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05302016 //Do not cache the information for next draw cycle.
2017 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
2018 ALOGI("%s: Unsupported layer count for mdp composition",
2019 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002020 mCachedFrame.reset();
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302021#ifdef DYNAMIC_FPS
2022 setDynRefreshRate(ctx, list);
2023#endif
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002024 return -1;
2025 }
2026
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002027 // Detect the start of animation and fall back to GPU only once to cache
2028 // all the layers in FB and display FB content untill animation completes.
2029 if(ctx->listStats[mDpy].isDisplayAnimating) {
2030 mCurrentFrame.needsRedraw = false;
2031 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2032 mCurrentFrame.needsRedraw = true;
2033 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2034 }
2035 setMDPCompLayerFlags(ctx, list);
2036 mCachedFrame.updateCounts(mCurrentFrame);
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302037#ifdef DYNAMIC_FPS
2038 setDynRefreshRate(ctx, list);
2039#endif
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07002040 ret = -1;
2041 return ret;
2042 } else {
2043 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2044 }
2045
Saurabh Shahb39f8152013-08-22 10:21:44 -07002046 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002047 if(isFrameDoable(ctx)) {
2048 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002049 // if AIV Video mode is enabled, drop all non AIV layers from the
2050 // external display list.
2051 if(ctx->listStats[mDpy].mAIVVideoMode) {
2052 dropNonAIVLayers(ctx, list);
2053 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002054
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07002055 // if tryFullFrame fails, try to push all video and secure RGB layers
2056 // to MDP for composition.
2057 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002058 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05302059 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002060 setMDPCompLayerFlags(ctx, list);
2061 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002062 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002063 reset(ctx);
2064 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2065 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002066 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07002067 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2068 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07002069 }
2070 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05302071 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2072 enablePartialUpdateForMDP3) {
2073 generateROI(ctx, list);
2074 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2075 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2076 }
2077 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002078 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2079 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002080 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07002081 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07002082
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002083 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002084 ALOGD("GEOMETRY change: %d",
2085 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002086 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07002087 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002088 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002089 }
2090
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002091#ifdef DYNAMIC_FPS
Praveena Pachipulusu66c8ef72014-11-25 18:47:54 +05302092 setDynRefreshRate(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002093#endif
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08002094 setPerfHint(ctx, list);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07002095
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002096 mCachedFrame.cacheAll(list);
2097 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002098 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002099}
2100
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002101bool MDPComp::allocSplitVGPipes(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302102
2103 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302104 int mdpIndex = mCurrentFrame.layerToMDP[index];
2105 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2106 info.pipeInfo = new MdpYUVPipeInfo;
2107 info.rot = NULL;
2108 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302109
2110 pipe_info.lIndex = ovutils::OV_INVALID;
2111 pipe_info.rIndex = ovutils::OV_INVALID;
2112
Saurabh Shahc62f3982014-03-05 14:28:26 -08002113 Overlay::PipeSpecs pipeSpecs;
2114 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2115 pipeSpecs.needsScaling = true;
2116 pipeSpecs.dpy = mDpy;
2117 pipeSpecs.fb = false;
2118
2119 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302120 if(pipe_info.lIndex == ovutils::OV_INVALID){
2121 bRet = false;
2122 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2123 __FUNCTION__);
2124 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002125 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302126 if(pipe_info.rIndex == ovutils::OV_INVALID){
2127 bRet = false;
2128 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2129 __FUNCTION__);
2130 }
2131 return bRet;
2132}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002133
2134int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2135 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002136 if (ctx->mPtorInfo.isActive()) {
2137 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002138 if (fd < 0) {
2139 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002140 }
2141 }
2142 return fd;
2143}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002144//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002145
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002146void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302147 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002148 //If 4k2k Yuv layer split is possible, and if
2149 //fbz is above 4k2k layer, increment fb zorder by 1
2150 //as we split 4k2k layer and increment zorder for right half
2151 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002152 if(!ctx)
2153 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002154 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302155 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2156 index++) {
2157 if(!mCurrentFrame.isFBComposed[index]) {
2158 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2159 mdpNextZOrder++;
2160 }
2161 mdpNextZOrder++;
2162 hwc_layer_1_t* layer = &list->hwLayers[index];
2163 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302164 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302165 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2166 mCurrentFrame.fbZ += 1;
2167 mdpNextZOrder++;
2168 //As we split 4kx2k yuv layer and program to 2 VG pipes
2169 //(if available) increase mdpcount by 1.
2170 mCurrentFrame.mdpCount++;
2171 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002172 }
2173 }
2174 }
radhakrishnac9a67412013-09-25 17:40:42 +05302175}
2176
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002177/*
2178 * Configures pipe(s) for MDP composition
2179 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002180int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002181 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002182 MdpPipeInfoNonSplit& mdp_info =
2183 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302184 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002185 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002186 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002187
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002188 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2189 __FUNCTION__, layer, zOrder, dest);
2190
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002191 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002192 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002193}
2194
Saurabh Shah88e4d272013-09-03 13:31:29 -07002195bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002196 hwc_display_contents_1_t* list) {
2197 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002198
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002199 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002200
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002201 hwc_layer_1_t* layer = &list->hwLayers[index];
2202 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302203 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002204 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302205 continue;
2206 }
2207 }
2208
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002209 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002210 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002211 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002212 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002213 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002214
Saurabh Shahc62f3982014-03-05 14:28:26 -08002215 Overlay::PipeSpecs pipeSpecs;
2216 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2217 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2218 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2219 (qdutils::MDPVersion::getInstance().is8x26() and
2220 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2221 pipeSpecs.dpy = mDpy;
2222 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002223 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002224
Saurabh Shahc62f3982014-03-05 14:28:26 -08002225 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2226
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002227 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002228 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002229 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002230 }
2231 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002232 return true;
2233}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002234
radhakrishnac9a67412013-09-25 17:40:42 +05302235int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2236 PipeLayerPair& PipeLayerPair) {
2237 MdpYUVPipeInfo& mdp_info =
2238 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2239 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302240 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302241 eDest lDest = mdp_info.lIndex;
2242 eDest rDest = mdp_info.rIndex;
2243
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002244 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302245 lDest, rDest, &PipeLayerPair.rot);
2246}
2247
Saurabh Shah88e4d272013-09-03 13:31:29 -07002248bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002249
Raj Kamal4393eaa2014-06-06 13:45:20 +05302250 if(!isEnabled() or !mModeOn) {
2251 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302252 return true;
2253 }
2254
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002255 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002256 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002257 sHandleTimeout = true;
2258 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002259
2260 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002261 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002262
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002263 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2264 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002265 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002266 if(mCurrentFrame.isFBComposed[i]) continue;
2267
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002268 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002269 private_handle_t *hnd = (private_handle_t *)layer->handle;
2270 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002271 if (!(layer->flags & HWC_COLOR_FILL)) {
2272 ALOGE("%s handle null", __FUNCTION__);
2273 return false;
2274 }
2275 // No PLAY for Color layer
2276 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2277 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002278 }
2279
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002280 int mdpIndex = mCurrentFrame.layerToMDP[i];
2281
Raj Kamal389d6e32014-08-04 14:43:24 +05302282 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302283 {
2284 MdpYUVPipeInfo& pipe_info =
2285 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2286 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2287 ovutils::eDest indexL = pipe_info.lIndex;
2288 ovutils::eDest indexR = pipe_info.rIndex;
2289 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302290 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302291 if(rot) {
2292 rot->queueBuffer(fd, offset);
2293 fd = rot->getDstMemId();
2294 offset = rot->getDstOffset();
2295 }
2296 if(indexL != ovutils::OV_INVALID) {
2297 ovutils::eDest destL = (ovutils::eDest)indexL;
2298 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2299 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2300 if (!ov.queueBuffer(fd, offset, destL)) {
2301 ALOGE("%s: queueBuffer failed for display:%d",
2302 __FUNCTION__, mDpy);
2303 return false;
2304 }
2305 }
2306
2307 if(indexR != ovutils::OV_INVALID) {
2308 ovutils::eDest destR = (ovutils::eDest)indexR;
2309 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2310 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2311 if (!ov.queueBuffer(fd, offset, destR)) {
2312 ALOGE("%s: queueBuffer failed for display:%d",
2313 __FUNCTION__, mDpy);
2314 return false;
2315 }
2316 }
2317 }
2318 else{
2319 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002320 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302321 ovutils::eDest dest = pipe_info.index;
2322 if(dest == ovutils::OV_INVALID) {
2323 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002324 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302325 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002326
radhakrishnac9a67412013-09-25 17:40:42 +05302327 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2328 continue;
2329 }
2330
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002331 int fd = hnd->fd;
2332 uint32_t offset = (uint32_t)hnd->offset;
2333 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2334 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002335 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002336 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002337 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002338 }
2339
radhakrishnac9a67412013-09-25 17:40:42 +05302340 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2341 using pipe: %d", __FUNCTION__, layer,
2342 hnd, dest );
2343
radhakrishnac9a67412013-09-25 17:40:42 +05302344 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2345 if(rot) {
2346 if(!rot->queueBuffer(fd, offset))
2347 return false;
2348 fd = rot->getDstMemId();
2349 offset = rot->getDstOffset();
2350 }
2351
2352 if (!ov.queueBuffer(fd, offset, dest)) {
2353 ALOGE("%s: queueBuffer failed for display:%d ",
2354 __FUNCTION__, mDpy);
2355 return false;
2356 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002357 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002358
2359 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002360 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002361 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002362}
2363
Saurabh Shah88e4d272013-09-03 13:31:29 -07002364//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002365
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002366void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302367 hwc_display_contents_1_t* list){
2368 //if 4kx2k yuv layer is totally present in either in left half
2369 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302370 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302371 if(mCurrentFrame.fbZ >= 0) {
2372 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2373 index++) {
2374 if(!mCurrentFrame.isFBComposed[index]) {
2375 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2376 mdpNextZOrder++;
2377 }
2378 mdpNextZOrder++;
2379 hwc_layer_1_t* layer = &list->hwLayers[index];
2380 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002381 if(isYUVSplitNeeded(hnd) ||
2382 (needs3DComposition(ctx,mDpy) &&
2383 get3DFormat(hnd) != HAL_NO_3D)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302384 hwc_rect_t dst = layer->displayFrame;
2385 if((dst.left > lSplit) || (dst.right < lSplit)) {
2386 mCurrentFrame.mdpCount += 1;
2387 }
2388 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2389 mCurrentFrame.fbZ += 1;
2390 mdpNextZOrder++;
2391 }
2392 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002393 }
radhakrishnac9a67412013-09-25 17:40:42 +05302394 }
2395}
2396
Saurabh Shah88e4d272013-09-03 13:31:29 -07002397bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002398 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002399
Saurabh Shahc62f3982014-03-05 14:28:26 -08002400 const int lSplit = getLeftSplit(ctx, mDpy);
2401 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002402 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002403 pipe_info.lIndex = ovutils::OV_INVALID;
2404 pipe_info.rIndex = ovutils::OV_INVALID;
2405
Saurabh Shahc62f3982014-03-05 14:28:26 -08002406 Overlay::PipeSpecs pipeSpecs;
2407 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2408 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2409 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2410 pipeSpecs.dpy = mDpy;
2411 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2412 pipeSpecs.fb = false;
2413
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002414 // Acquire pipe only for the updating half
2415 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2416 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2417
2418 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002419 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002420 if(pipe_info.lIndex == ovutils::OV_INVALID)
2421 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002422 }
2423
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002424 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002425 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2426 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002427 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002428 return false;
2429 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002430
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002431 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002432}
2433
Saurabh Shah88e4d272013-09-03 13:31:29 -07002434bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002435 hwc_display_contents_1_t* list) {
2436 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002437
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002438 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002439
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002440 hwc_layer_1_t* layer = &list->hwLayers[index];
2441 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302442 hwc_rect_t dst = layer->displayFrame;
2443 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302444 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302445 if((dst.left > lSplit)||(dst.right < lSplit)){
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002446 if(allocSplitVGPipes(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302447 continue;
2448 }
2449 }
2450 }
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002451 //XXX: Check for forced 2D composition
2452 if(needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D)
2453 if(allocSplitVGPipes(ctx,index))
2454 continue;
2455
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002456 int mdpIndex = mCurrentFrame.layerToMDP[index];
2457 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002458 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002459 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002460 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002461
Saurabh Shahc62f3982014-03-05 14:28:26 -08002462 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2463 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2464 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002465 return false;
2466 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002467 }
2468 return true;
2469}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002470
radhakrishnac9a67412013-09-25 17:40:42 +05302471int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2472 PipeLayerPair& PipeLayerPair) {
2473 const int lSplit = getLeftSplit(ctx, mDpy);
2474 hwc_rect_t dst = layer->displayFrame;
2475 if((dst.left > lSplit)||(dst.right < lSplit)){
2476 MdpYUVPipeInfo& mdp_info =
2477 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2478 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302479 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302480 eDest lDest = mdp_info.lIndex;
2481 eDest rDest = mdp_info.rIndex;
2482
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002483 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302484 lDest, rDest, &PipeLayerPair.rot);
2485 }
2486 else{
2487 return configure(ctx, layer, PipeLayerPair);
2488 }
2489}
2490
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002491/*
2492 * Configures pipe(s) for MDP composition
2493 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002494int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002495 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002496 MdpPipeInfoSplit& mdp_info =
2497 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002498 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302499 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002500 eDest lDest = mdp_info.lIndex;
2501 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002502
2503 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002504 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002505
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002506 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002507 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002508}
2509
Saurabh Shah88e4d272013-09-03 13:31:29 -07002510bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002511
Raj Kamal4393eaa2014-06-06 13:45:20 +05302512 if(!isEnabled() or !mModeOn) {
2513 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302514 return true;
2515 }
2516
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002517 // Set the Handle timeout to true for MDP or MIXED composition.
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002518 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount &&
2519 !(needs3DComposition(ctx, HWC_DISPLAY_PRIMARY) ||
2520 needs3DComposition(ctx, HWC_DISPLAY_EXTERNAL))) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002521 sHandleTimeout = true;
2522 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002523
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002524 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002525 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002526
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002527 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2528 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002529 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002530 if(mCurrentFrame.isFBComposed[i]) continue;
2531
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002532 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002533 private_handle_t *hnd = (private_handle_t *)layer->handle;
2534 if(!hnd) {
2535 ALOGE("%s handle null", __FUNCTION__);
2536 return false;
2537 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002538
2539 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2540 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002541 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002542
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002543 int mdpIndex = mCurrentFrame.layerToMDP[i];
2544
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002545 if((isYUVSplitNeeded(hnd) && sEnableYUVsplit) ||
2546 (needs3DComposition(ctx, mDpy) && get3DFormat(hnd) != HAL_NO_3D))
radhakrishnac9a67412013-09-25 17:40:42 +05302547 {
2548 MdpYUVPipeInfo& pipe_info =
2549 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2550 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2551 ovutils::eDest indexL = pipe_info.lIndex;
2552 ovutils::eDest indexR = pipe_info.rIndex;
2553 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302554 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302555 if(rot) {
2556 rot->queueBuffer(fd, offset);
2557 fd = rot->getDstMemId();
2558 offset = rot->getDstOffset();
2559 }
2560 if(indexL != ovutils::OV_INVALID) {
2561 ovutils::eDest destL = (ovutils::eDest)indexL;
2562 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2563 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2564 if (!ov.queueBuffer(fd, offset, destL)) {
2565 ALOGE("%s: queueBuffer failed for display:%d",
2566 __FUNCTION__, mDpy);
2567 return false;
2568 }
2569 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002570
radhakrishnac9a67412013-09-25 17:40:42 +05302571 if(indexR != ovutils::OV_INVALID) {
2572 ovutils::eDest destR = (ovutils::eDest)indexR;
2573 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2574 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2575 if (!ov.queueBuffer(fd, offset, destR)) {
2576 ALOGE("%s: queueBuffer failed for display:%d",
2577 __FUNCTION__, mDpy);
2578 return false;
2579 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002580 }
2581 }
radhakrishnac9a67412013-09-25 17:40:42 +05302582 else{
2583 MdpPipeInfoSplit& pipe_info =
2584 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2585 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002586
radhakrishnac9a67412013-09-25 17:40:42 +05302587 ovutils::eDest indexL = pipe_info.lIndex;
2588 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002589
radhakrishnac9a67412013-09-25 17:40:42 +05302590 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002591 uint32_t offset = (uint32_t)hnd->offset;
2592 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2593 if (!mDpy && (index != -1)) {
2594 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2595 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002596 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002597 }
radhakrishnac9a67412013-09-25 17:40:42 +05302598
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002599 if(ctx->mAD->draw(ctx, fd, offset)) {
2600 fd = ctx->mAD->getDstFd();
2601 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002602 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002603
radhakrishnac9a67412013-09-25 17:40:42 +05302604 if(rot) {
2605 rot->queueBuffer(fd, offset);
2606 fd = rot->getDstMemId();
2607 offset = rot->getDstOffset();
2608 }
2609
2610 //************* play left mixer **********
2611 if(indexL != ovutils::OV_INVALID) {
2612 ovutils::eDest destL = (ovutils::eDest)indexL;
2613 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2614 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2615 if (!ov.queueBuffer(fd, offset, destL)) {
2616 ALOGE("%s: queueBuffer failed for left mixer",
2617 __FUNCTION__);
2618 return false;
2619 }
2620 }
2621
2622 //************* play right mixer **********
2623 if(indexR != ovutils::OV_INVALID) {
2624 ovutils::eDest destR = (ovutils::eDest)indexR;
2625 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2626 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2627 if (!ov.queueBuffer(fd, offset, destR)) {
2628 ALOGE("%s: queueBuffer failed for right mixer",
2629 __FUNCTION__);
2630 return false;
2631 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002632 }
2633 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002634
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002635 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2636 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002637
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002638 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002639}
Saurabh Shahab47c692014-02-12 18:45:57 -08002640
2641//================MDPCompSrcSplit==============================================
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002642
2643bool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
2644 hwc_display_contents_1_t* list) {
2645 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2646 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
2647
2648 for(int i = numAppLayers - 1; i >= 0; i--) {
2649 if(!isValidRect(visibleRect)) {
2650 mCurrentFrame.drop[i] = true;
2651 mCurrentFrame.dropCount++;
2652 continue;
2653 }
2654
2655 const hwc_layer_1_t* layer = &list->hwLayers[i];
2656 hwc_rect_t dstRect = layer->displayFrame;
2657 hwc_rect_t res = getIntersection(visibleRect, dstRect);
2658
2659 if(!isValidRect(res)) {
2660 mCurrentFrame.drop[i] = true;
2661 mCurrentFrame.dropCount++;
2662 } else {
2663 /* Reset frame ROI when any layer which needs scaling also needs ROI
2664 * cropping */
2665 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
2666 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
2667 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2668 mCurrentFrame.dropCount = 0;
2669 return false;
2670 }
2671
2672 /* deduct any opaque region from visibleRect */
2673 if (layer->blending == HWC_BLENDING_NONE &&
2674 layer->planeAlpha == 0xFF)
2675 visibleRect = deductRect(visibleRect, res);
2676 }
2677 }
2678 return true;
2679}
2680
2681/*
2682 * HW Limitation: ping pong split can always split the ping pong output
2683 * equally across two DSI's. So the ROI programmed should be of equal width
2684 * for both the halves
2685 */
2686void MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
2687 hwc_display_contents_1_t* list) {
2688 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
2689
2690
2691 if(!canPartialUpdate(ctx, list))
2692 return;
2693
2694 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
2695 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
2696 (int)ctx->dpyAttr[mDpy].yres};
2697
2698 for(int index = 0; index < numAppLayers; index++ ) {
2699 hwc_layer_1_t* layer = &list->hwLayers[index];
2700
2701 // If we have a RGB layer which needs rotation, no partial update
2702 if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
2703 return;
2704
2705 if ((mCachedFrame.hnd[index] != layer->handle) ||
2706 isYuvBuffer((private_handle_t *)layer->handle)) {
2707 hwc_rect_t dst = layer->displayFrame;
2708 hwc_rect_t updatingRect = dst;
2709
2710#ifdef QCOM_BSP
2711 if(!needsScaling(layer) && !layer->transform)
2712 {
2713 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
2714 int x_off = dst.left - src.left;
2715 int y_off = dst.top - src.top;
2716 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
2717 }
2718#endif
2719
2720 roi = getUnion(roi, updatingRect);
2721 }
2722 }
2723
2724 /* No layer is updating. Still SF wants a refresh.*/
2725 if(!isValidRect(roi))
2726 return;
2727
2728 roi = expandROIFromMidPoint(roi, fullFrame);
2729
2730 hwc_rect lFrame = fullFrame;
2731 lFrame.right /= 2;
2732 hwc_rect lRoi = getIntersection(roi, lFrame);
2733
2734 // Align ROI coordinates to panel restrictions
2735 lRoi = getSanitizeROI(lRoi, lFrame);
2736
2737 hwc_rect rFrame = fullFrame;
2738 rFrame.left = lFrame.right;
2739 hwc_rect rRoi = getIntersection(roi, rFrame);
2740
2741 // Align ROI coordinates to panel restrictions
2742 rRoi = getSanitizeROI(rRoi, rFrame);
2743
2744 roi = getUnion(lRoi, rRoi);
2745
2746 ctx->listStats[mDpy].lRoi = roi;
2747 if(!validateAndApplyROI(ctx, list))
2748 resetROI(ctx, mDpy);
2749
2750 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
2751 __FUNCTION__,
2752 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
2753 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
2754 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
2755 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
2756}
2757
Saurabh Shahab47c692014-02-12 18:45:57 -08002758bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002759 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002760 private_handle_t *hnd = (private_handle_t *)layer->handle;
2761 hwc_rect_t dst = layer->displayFrame;
2762 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2763 pipe_info.lIndex = ovutils::OV_INVALID;
2764 pipe_info.rIndex = ovutils::OV_INVALID;
2765
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002766 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
2767 trimAgainstROI(ctx,crop, dst);
2768
Saurabh Shahab47c692014-02-12 18:45:57 -08002769 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2770 //should have a higher priority than the right one. Pipe priorities are
2771 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002772
Saurabh Shahc62f3982014-03-05 14:28:26 -08002773 Overlay::PipeSpecs pipeSpecs;
2774 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2775 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2776 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2777 pipeSpecs.dpy = mDpy;
2778 pipeSpecs.fb = false;
2779
Saurabh Shahab47c692014-02-12 18:45:57 -08002780 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002781 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002782 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002783 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002784 }
2785
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002786 /* Use 2 pipes IF
2787 a) Layer's crop width is > 2048 or
2788 b) Layer's dest width > 2048 or
2789 c) On primary, driver has indicated with caps to split always. This is
2790 based on an empirically derived value of panel height. Applied only
2791 if the layer's width is > mixer's width
2792 */
2793
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302794 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002795 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302796 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002797 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2798 const uint32_t dstWidth = dst.right - dst.left;
2799 const uint32_t dstHeight = dst.bottom - dst.top;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002800 uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002801 crop.right - crop.left;
Saurabh Shah05f4e222015-02-05 14:36:22 -08002802 uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
Saurabh Shah514759d2014-11-11 18:02:24 -08002803 crop.bottom - crop.top;
2804 //Approximation to actual clock, ignoring the common factors in pipe and
2805 //mixer cases like line_time
2806 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2807 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002808
Saurabh Shah05f4e222015-02-05 14:36:22 -08002809 const uint32_t downscale = getRotDownscale(ctx, layer);
2810 if(downscale) {
2811 cropWidth /= downscale;
2812 cropHeight /= downscale;
2813 }
2814
Jeykumar Sankaran39305802014-12-12 17:55:57 -08002815 if(dstWidth > mdpHw.getMaxPipeWidth() or
2816 cropWidth > mdpHw.getMaxPipeWidth() or
Saurabh Shah514759d2014-11-11 18:02:24 -08002817 (primarySplitAlways and
2818 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002819 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002820 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002821 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002822 }
2823
Jeykumar Sankaran89e23ab2015-01-28 15:57:46 -08002824 if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2825 pipe_info.rIndex)) {
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002826 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002827 }
2828 }
2829
2830 return true;
2831}
2832
Saurabh Shahab47c692014-02-12 18:45:57 -08002833int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2834 PipeLayerPair& PipeLayerPair) {
2835 private_handle_t *hnd = (private_handle_t *)layer->handle;
2836 if(!hnd) {
2837 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2838 return -1;
2839 }
2840 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2841 MdpPipeInfoSplit& mdp_info =
2842 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2843 Rotator **rot = &PipeLayerPair.rot;
2844 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002845 eDest lDest = mdp_info.lIndex;
2846 eDest rDest = mdp_info.rIndex;
2847 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2848 hwc_rect_t dst = layer->displayFrame;
2849 int transform = layer->transform;
2850 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002851 int rotFlags = ROT_FLAGS_NONE;
Sushil Chauhan65e26302015-01-14 10:48:57 -08002852 uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Saurabh Shahab47c692014-02-12 18:45:57 -08002853 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002854 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahab47c692014-02-12 18:45:57 -08002855
2856 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2857 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2858
Jeykumar Sankaranaedd1432015-01-15 11:25:03 -08002859 if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
2860 /* MDP driver crops layer coordinates against ROI in Non-Split
2861 * and Split MDP comp. But HWC needs to crop them for source split.
2862 * Reason: 1) Source split is efficient only when the final effective
2863 * load is distributed evenly across mixers.
2864 * 2) We have to know the effective width of the layer that
2865 * the ROI needs to find the no. of pipes the layer needs.
2866 */
2867 trimAgainstROI(ctx, crop, dst);
2868 }
2869
Naseer Ahmed6bbd0a12015-01-23 11:57:10 -05002870 if(needs3DComposition(ctx, mDpy) &&
2871 get3DFormat(hnd) != HAL_NO_3D){
2872 return configure3DVideo(ctx, layer, mDpy, mdpFlags, z, lDest,
2873 rDest, &PipeLayerPair.rot);
2874 }
2875
Saurabh Shahab47c692014-02-12 18:45:57 -08002876 // Handle R/B swap
2877 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2878 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2879 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2880 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2881 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2882 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002883 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002884 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2885 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002886 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002887 /* Calculate the external display position based on MDP downscale,
2888 ActionSafe, and extorientation features. */
2889 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002890
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002891 int downscale = getRotDownscale(ctx, layer);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002892 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002893
2894 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2895 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002896 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002897 }
2898
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002899 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002900 (*rot) = ctx->mRotMgr->getNext();
2901 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002902 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002903 //If the video is using a single pipe, enable BWC
2904 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002905 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2906 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002907 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002908 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002909 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002910 ALOGE("%s: configRotator failed!", __FUNCTION__);
2911 return -1;
2912 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002913 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002914 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002915 }
2916
2917 //If 2 pipes being used, divide layer into half, crop and dst
2918 hwc_rect_t cropL = crop;
2919 hwc_rect_t cropR = crop;
2920 hwc_rect_t dstL = dst;
2921 hwc_rect_t dstR = dst;
2922 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2923 cropL.right = (crop.right + crop.left) / 2;
2924 cropR.left = cropL.right;
2925 sanitizeSourceCrop(cropL, cropR, hnd);
2926
Saurabh Shahb729b192014-08-15 18:04:24 -07002927 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002928 //Swap crops on H flip since 2 pipes are being used
2929 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2930 hwc_rect_t tmp = cropL;
2931 cropL = cropR;
2932 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002933 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002934 }
2935
Saurabh Shahb729b192014-08-15 18:04:24 -07002936 //cropSwap trick: If the src and dst widths are both odd, let us say
2937 //2507, then splitting both into half would cause left width to be 1253
2938 //and right 1254. If crop is swapped because of H flip, this will cause
2939 //left crop width to be 1254, whereas left dst width remains 1253, thus
2940 //inducing a scaling that is unaccounted for. To overcome that we add 1
2941 //to the dst width if there is a cropSwap. So if the original width was
2942 //2507, the left dst width will be 1254. Even if the original width was
2943 //even for ex: 2508, the left dst width will still remain 1254.
2944 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002945 dstR.left = dstL.right;
2946 }
2947
2948 //For the mdp, since either we are pre-rotating or MDP does flips
2949 orient = OVERLAY_TRANSFORM_0;
2950 transform = 0;
2951
2952 //configure left pipe
2953 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002954 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002955 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2956 (ovutils::eBlending) getBlending(layer->blending));
2957
2958 if(configMdp(ctx->mOverlay, pargL, orient,
2959 cropL, dstL, metadata, lDest) < 0) {
2960 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2961 return -1;
2962 }
2963 }
2964
2965 //configure right pipe
2966 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002967 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002968 static_cast<eRotFlags>(rotFlags),
2969 layer->planeAlpha,
2970 (ovutils::eBlending) getBlending(layer->blending));
2971 if(configMdp(ctx->mOverlay, pargR, orient,
2972 cropR, dstR, metadata, rDest) < 0) {
2973 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2974 return -1;
2975 }
2976 }
2977
2978 return 0;
2979}
2980
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08002981bool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2982 Locker::Autolock _l(ctx->mDrawLock);
2983 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2984 char path[MAX_SYSFS_FILE_PATH];
2985 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2986 int fd = open(path, O_RDONLY);
2987 if(fd < 0) {
2988 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2989 return -1;
2990 }
2991 char value[4];
2992 ssize_t size_read = read(fd, value, sizeof(value)-1);
2993 if(size_read <= 0) {
2994 ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2995 close(fd);
2996 return -1;
2997 }
2998 close(fd);
2999 value[size_read] = '\0';
3000 return atoi(value);
3001}
3002
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003003int MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
3004 Locker::Autolock _l(ctx->mDrawLock);
3005 const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
3006 char path[MAX_SYSFS_FILE_PATH];
3007 snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
3008 int fd = open(path, O_WRONLY);
3009 if(fd < 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003010 ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003011 return -1;
3012 }
3013 char value[4];
3014 snprintf(value, sizeof(value), "%d", (int)enable);
3015 ssize_t ret = write(fd, value, strlen(value));
3016 if(ret <= 0) {
Jeykumar Sankaranf4eb9fb2014-12-04 13:06:43 -08003017 ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003018 close(fd);
3019 return -1;
3020 }
3021 close(fd);
Jeykumar Sankaran53b05f22014-08-05 11:27:03 -07003022 return 0;
3023}
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003024
3025bool MDPComp::loadPerfLib() {
3026 char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3027 bool success = false;
3028 if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3029 ALOGE("vendor library not set in ro.vendor.extension_library");
3030 return false;
3031 }
3032
3033 sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3034 if(sLibPerfHint) {
3035 *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3036 *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3037 if (!sPerfLockAcquire || !sPerfLockRelease) {
3038 ALOGE("Failed to load symbols for perfLock");
3039 dlclose(sLibPerfHint);
3040 sLibPerfHint = NULL;
3041 return false;
3042 }
3043 success = true;
3044 ALOGI("Successfully Loaded perf hint API's");
3045 } else {
3046 ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3047 }
3048 return success;
3049}
3050
3051void MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3052 if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3053 return;
3054 }
3055 static int count = sPerfHintWindow;
3056 static int perflockFlag = 0;
3057
3058 /* Send hint to mpctl when single layer is updated
3059 * for a successful number of windows. Hint release
3060 * happens immediately upon multiple layer update.
3061 */
3062 if (onlyVideosUpdating(ctx, list)) {
3063 if(count) {
3064 count--;
3065 }
3066 } else {
3067 if (perflockFlag) {
3068 perflockFlag = 0;
3069 sPerfLockRelease(sPerfLockHandle);
3070 }
3071 count = sPerfHintWindow;
3072 }
3073 if (count == 0 && !perflockFlag) {
3074 int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3075 sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3076 &perfHint, sizeof(perfHint)/sizeof(int));
Arun Kumar K.R8b927022015-02-24 12:34:21 -08003077 if(sPerfLockHandle > 0) {
Arun Kumar K.R299bcda2014-12-18 19:36:40 -08003078 perflockFlag = 1;
3079 }
3080 }
3081}
3082
Naseer Ahmed7c958d42012-07-31 18:57:03 -07003083}; //namespace
3084