blob: 9872049deceeb2a369adcc6b64295ccfc30de58c [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002 * Copyright (C) 2012-2014, 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>
Tatenda Chipeperekwaaf2c0042014-09-17 12:55:01 -070022#include "hdmi.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080023#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080024#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070025#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070026#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
Sushil Chauhandefd3522014-05-13 18:17:12 -070028#include "hwc_copybit.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080029
Saurabh Shah85234ec2013-04-12 17:09:00 -070030using namespace overlay;
Saurabh Shahbd2d0832013-04-04 14:33:08 -070031using namespace qdutils;
Saurabh Shahacf10202013-02-26 10:15:15 -080032using namespace overlay::utils;
33namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035namespace qhwc {
36
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080037//==============MDPComp========================================================
38
Saurabh Shah59562ff2014-09-30 16:13:12 -070039IdleInvalidator *MDPComp::sIdleInvalidator = NULL;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070040bool MDPComp::sIdleFallBack = false;
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -080041bool MDPComp::sHandleTimeout = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070042bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050043bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070044bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -070045int MDPComp::sSimulationFlags = 0;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -070046int MDPComp::sMaxPipesPerMixer = 0;
Raj Kamal389d6e32014-08-04 14:43:24 +053047bool MDPComp::sEnableYUVsplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +053049bool MDPComp::enablePartialUpdateForMDP3 = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070050MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Saurabh Shah60e8bde2014-04-30 14:46:03 -070051 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
52 sSrcSplitEnabled = true;
53 return new MDPCompSrcSplit(dpy);
54 } else if(isDisplaySplit(ctx, dpy)) {
Saurabh Shah88e4d272013-09-03 13:31:29 -070055 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080056 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070057 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058}
59
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080060MDPComp::MDPComp(int dpy):mDpy(dpy){};
61
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070062void MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070064 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
65 return;
66
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070068 (mDpy == 0) ? "\"PRIMARY\"" :
69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070070 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
71 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080072 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
74 (mCurrentFrame.needsRedraw? "YES" : "NO"),
75 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -070076 if(isDisplaySplit(ctx, mDpy)) {
77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
78 "Right: [%d, %d, %d, %d] \n",
79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
80 ctx->listStats[mDpy].lRoi.right,
81 ctx->listStats[mDpy].lRoi.bottom,
82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
83 ctx->listStats[mDpy].rRoi.right,
84 ctx->listStats[mDpy].rRoi.bottom);
85 } else {
86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
88 ctx->listStats[mDpy].lRoi.right,
89 ctx->listStats[mDpy].lRoi.bottom);
90 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080091 dumpsys_log(buf," --------------------------------------------- \n");
92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
93 dumpsys_log(buf," --------------------------------------------- \n");
94 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
96 index,
97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070098 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700100 (mCurrentFrame.drop[index] ? "DROP" :
101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
104 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800105}
106
107bool MDPComp::init(hwc_context_t *ctx) {
108
109 if(!ctx) {
110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
111 return false;
112 }
113
Saurabh Shah59562ff2014-09-30 16:13:12 -0700114 char property[PROPERTY_VALUE_MAX] = {0};
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800115
116 sEnabled = false;
Dileep Kumar Reddid8e601d2014-10-28 18:20:43 +0530117 if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
118 (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800119 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
120 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800121 sEnabled = true;
122 }
123
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700124 sEnableMixedMode = true;
125 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
126 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
127 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
128 sEnableMixedMode = false;
129 }
130
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700131 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
132
133 /* MDSS_MDP_STAGE_UNUSED and MDSS_MDP_STAGE_BASE are not available for MDP
134 * composition. */
135 sMaxPipesPerMixer = (int)mdpVersion.getBlendStages() - 2;
136 if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
Saurabh Shah85234ec2013-04-12 17:09:00 -0700137 int val = atoi(property);
138 if(val >= 0)
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700139 sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800140 }
141
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400142 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
Saurabh Shah59562ff2014-09-30 16:13:12 -0700143 sIdleInvalidator = IdleInvalidator::getInstance();
144 if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
145 delete sIdleInvalidator;
146 sIdleInvalidator = NULL;
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400147 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800148 }
radhakrishnac9a67412013-09-25 17:40:42 +0530149
Saurabh Shah7c727642014-06-02 15:47:14 -0700150 if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
Saurabh Shahc46cf9d2014-07-02 15:22:34 -0700151 !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
Saurabh Shah7c727642014-06-02 15:47:14 -0700152 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
153 (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
154 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
Raj Kamal389d6e32014-08-04 14:43:24 +0530155 sEnableYUVsplit = true;
radhakrishnac9a67412013-09-25 17:40:42 +0530156 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700157
Dileep Kumar Reddic6ef3472014-09-24 19:07:08 +0530158 bool defaultPTOR = false;
159 //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
160 //8x16 and 8x39 targets by default
161 if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
162 (qdutils::MDPVersion::getInstance().is8x16() ||
163 qdutils::MDPVersion::getInstance().is8x39())) {
164 defaultPTOR = true;
165 }
166
167 if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
168 (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700169 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
170 HWC_DISPLAY_PRIMARY);
171 }
172
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +0530173 if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
174 (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
175 enablePartialUpdateForMDP3 = true;
176 }
177
178 if(!enablePartialUpdateForMDP3 &&
179 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
180 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
181 enablePartialUpdateForMDP3 = true;
182 }
183
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700184 return true;
185}
186
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800187void MDPComp::reset(hwc_context_t *ctx) {
188 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700189 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800190 ctx->mOverlay->clear(mDpy);
191 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700192}
193
Raj Kamal4393eaa2014-06-06 13:45:20 +0530194void MDPComp::reset() {
195 sHandleTimeout = false;
196 mModeOn = false;
197}
198
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700199void MDPComp::timeout_handler(void *udata) {
200 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
201
202 if(!ctx) {
203 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
204 return;
205 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800206 Locker::Autolock _l(ctx->mDrawLock);
207 // Handle timeout event only if the previous composition is MDP or MIXED.
208 if(!sHandleTimeout) {
209 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
210 return;
211 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700212 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700213 ALOGE("%s: HWC proc not registered", __FUNCTION__);
214 return;
215 }
216 sIdleFallBack = true;
217 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700218 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700219}
220
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700221void MDPComp::setMaxPipesPerMixer(const uint32_t value) {
222 qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
223 uint32_t maxSupported = (int)mdpVersion.getBlendStages() - 2;
224 if(value > maxSupported) {
225 ALOGW("%s: Input exceeds max value supported. Setting to"
226 "max value: %d", __FUNCTION__, maxSupported);
227 }
228 sMaxPipesPerMixer = min(value, maxSupported);
229}
230
Saurabh Shah59562ff2014-09-30 16:13:12 -0700231void MDPComp::setIdleTimeout(const uint32_t& timeout) {
232 enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
233
234 if(sIdleInvalidator) {
235 if(timeout <= ONE_REFRESH_PERIOD_MS) {
236 //If the specified timeout is < 1 draw cycle worth, "virtually"
237 //disable idle timeout. The ideal way for clients to disable
238 //timeout is to set it to 0
239 sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
240 ALOGI("Disabled idle timeout");
241 return;
242 }
243 sIdleInvalidator->setIdleTimeout(timeout);
244 ALOGI("Idle timeout set to %u", timeout);
245 } else {
246 ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
247 }
248}
249
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800250void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800251 hwc_display_contents_1_t* list) {
252 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800253
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800254 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800255 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800256 if(!mCurrentFrame.isFBComposed[index]) {
257 layerProp[index].mFlags |= HWC_MDPCOMP;
258 layer->compositionType = HWC_OVERLAY;
259 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800260 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700261 /* Drop the layer when its already present in FB OR when it lies
262 * outside frame's ROI */
263 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700265 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800266 }
267 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700268}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500269
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800270void MDPComp::setRedraw(hwc_context_t *ctx,
271 hwc_display_contents_1_t* list) {
272 mCurrentFrame.needsRedraw = false;
273 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
274 (list->flags & HWC_GEOMETRY_CHANGED) ||
275 isSkipPresent(ctx, mDpy)) {
276 mCurrentFrame.needsRedraw = true;
277 }
278}
279
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800280MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahf7fad542014-08-14 10:11:36 -0700281 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
Saurabh Shahaa236822013-04-24 18:07:26 -0700282 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800283}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800284
Saurabh Shahaa236822013-04-24 18:07:26 -0700285void MDPComp::FrameInfo::reset(const int& numLayers) {
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700286 for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800287 if(mdpToLayer[i].pipeInfo) {
288 delete mdpToLayer[i].pipeInfo;
289 mdpToLayer[i].pipeInfo = NULL;
290 //We dont own the rotator
291 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800292 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800293 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800294
295 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
296 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700297 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800298
Saurabh Shahaa236822013-04-24 18:07:26 -0700299 layerCount = numLayers;
300 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800301 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700302 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800303 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800304}
305
Saurabh Shahaa236822013-04-24 18:07:26 -0700306void MDPComp::FrameInfo::map() {
307 // populate layer and MDP maps
308 int mdpIdx = 0;
309 for(int idx = 0; idx < layerCount; idx++) {
310 if(!isFBComposed[idx]) {
311 mdpToLayer[mdpIdx].listIndex = idx;
312 layerToMDP[idx] = mdpIdx++;
313 }
314 }
315}
316
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800317MDPComp::LayerCache::LayerCache() {
318 reset();
319}
320
321void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700322 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530323 memset(&isFBComposed, true, sizeof(isFBComposed));
324 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800325 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700326}
327
328void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530329 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700330 for(int i = 0; i < numAppLayers; i++) {
331 hnd[i] = list->hwLayers[i].handle;
332 }
333}
334
335void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700336 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530337 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
338 memcpy(&drop, &curFrame.drop, sizeof(drop));
339}
340
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800341bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
342 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530343 if(layerCount != curFrame.layerCount)
344 return false;
345 for(int i = 0; i < curFrame.layerCount; i++) {
346 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
347 (curFrame.drop[i] != drop[i])) {
348 return false;
349 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800350 if(curFrame.isFBComposed[i] &&
351 (hnd[i] != list->hwLayers[i].handle)){
352 return false;
353 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530354 }
355 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800356}
357
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700358bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
359 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800360 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700361 (not isValidDimension(ctx,layer))
362 //More conditions here, SKIP, sRGB+Blend etc
363 ) {
364 return false;
365 }
366 return true;
367}
368
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530369bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800370 private_handle_t *hnd = (private_handle_t *)layer->handle;
371
372 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700373 if (layer->flags & HWC_COLOR_FILL) {
374 // Color layer
375 return true;
376 }
Ramkumar Radhakrishnan0cabf212014-09-08 20:07:49 -0700377 ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800378 return false;
379 }
380
Naseer Ahmede850a802013-09-06 13:12:52 -0400381 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400382 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400383 return false;
384
Saurabh Shah62e1d732013-09-17 10:44:05 -0700385 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700386 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahb6810df2014-06-17 16:00:22 -0700387 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
Saurabh Shahe28a4022014-06-13 11:41:13 -0700388 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
389 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700390 int dst_w = dst.right - dst.left;
391 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800392 float w_scale = ((float)crop_w / (float)dst_w);
393 float h_scale = ((float)crop_h / (float)dst_h);
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530394 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shah4fdde762013-04-30 18:47:33 -0700395
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800396 /* Workaround for MDP HW limitation in DSI command mode panels where
397 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
398 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530399 * There also is a HW limilation in MDP, minimum block size is 2x2
400 * Fallback to GPU if height is less than 2.
401 */
Saurabh Shah189f23d2014-09-26 17:21:00 -0700402 if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800403 return false;
404
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800405 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530406 const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800407 const float w_dscale = w_scale;
408 const float h_dscale = h_scale;
409
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800410 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700411
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530412 if(!mdpHw.supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700413 /* On targets that doesnt support Decimation (eg.,8x26)
414 * maximum downscale support is overlay pipe downscale.
415 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400416 if(crop_w > (int) mdpHw.getMaxMixerWidth() ||
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530417 w_dscale > maxMDPDownscale ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700418 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800419 return false;
420 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700421 // Decimation on macrotile format layers is not supported.
422 if(isTileRendered(hnd)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530423 /* Bail out if
424 * 1. Src crop > Mixer limit on nonsplit MDPComp
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700425 * 2. exceeds maximum downscale limit
426 */
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400427 if(((crop_w > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530428 !sSrcSplitEnabled) ||
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700429 w_dscale > maxMDPDownscale ||
430 h_dscale > maxMDPDownscale) {
431 return false;
432 }
433 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800434 return false;
435 }
436 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700437 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700438 return false;
439 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700440 }
441
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800442 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530443 const uint32_t upscale = mdpHw.getMaxMDPUpscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800444 const float w_uscale = 1.0f / w_scale;
445 const float h_uscale = 1.0f / h_scale;
446
447 if(w_uscale > upscale || h_uscale > upscale)
448 return false;
449 }
450
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800451 return true;
452}
453
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800454bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700455 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800456
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800457 if(!isEnabled()) {
458 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700459 ret = false;
Raj Kamal068f4572014-04-14 16:14:06 +0530460 } else if((qdutils::MDPVersion::getInstance().is8x26() ||
Prabhanjan Kandula958ffa92014-05-12 14:56:56 +0530461 qdutils::MDPVersion::getInstance().is8x16() ||
462 qdutils::MDPVersion::getInstance().is8x39()) &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800463 ctx->mVideoTransFlag &&
464 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700465 //1 Padding round to shift pipes across mixers
466 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
467 __FUNCTION__);
468 ret = false;
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700469 } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
470 /* TODO: freeing up all the resources only for the targets having total
471 number of pipes < 8. Need to analyze number of VIG pipes used
472 for primary in previous draw cycle and accordingly decide
473 whether to fall back to full GPU comp or video only comp
474 */
475 if(isSecondaryConfiguring(ctx)) {
476 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
477 __FUNCTION__);
478 ret = false;
479 } else if(ctx->isPaddingRound) {
480 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
481 __FUNCTION__,mDpy);
482 ret = false;
483 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800484 } else if (ctx->isDMAStateChanging) {
485 // Bail out if a padding round has been invoked in order to switch DMA
486 // state to block mode. We need this to cater for the case when a layer
487 // requires rotation in the current frame.
488 ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
489 __FUNCTION__);
490 return false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700491 }
Tatenda Chipeperekwadc8d7082014-11-04 16:41:50 -0800492
Saurabh Shahaa236822013-04-24 18:07:26 -0700493 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800494}
495
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800496void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
497 hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
498 fbRect = getIntersection(fbRect, roi);
499}
500
501/* 1) Identify layers that are not visible or lying outside the updating ROI and
502 * drop them from composition.
503 * 2) If we have a scaling layer which needs cropping against generated
504 * ROI, reset ROI to full resolution. */
505bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
506 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700507 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800508 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800509
510 for(int i = numAppLayers - 1; i >= 0; i--){
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800511 if(!isValidRect(visibleRect)) {
512 mCurrentFrame.drop[i] = true;
513 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800514 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800515 }
516
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700517 const hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700518 hwc_rect_t dstRect = layer->displayFrame;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800519 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700520
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700521 if(!isValidRect(res)) {
522 mCurrentFrame.drop[i] = true;
523 mCurrentFrame.dropCount++;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800524 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700525 /* Reset frame ROI when any layer which needs scaling also needs ROI
526 * cropping */
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800527 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800528 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700529 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
530 mCurrentFrame.dropCount = 0;
531 return false;
532 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800533
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800534 /* deduct any opaque region from visibleRect */
535 if (layer->blending == HWC_BLENDING_NONE)
536 visibleRect = deductRect(visibleRect, res);
537 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700538 }
539 return true;
540}
541
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800542/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
543 * are updating. If DirtyRegion is applicable, calculate it by accounting all
544 * the changing layer's dirtyRegion. */
545void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
546 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700547 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800548 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700549 return;
550
551 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800552 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
553 (int)ctx->dpyAttr[mDpy].yres};
554
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700555 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800556 hwc_layer_1_t* layer = &list->hwLayers[index];
557 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800558 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700559 hwc_rect_t dst = layer->displayFrame;
560 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800561
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800562#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800563 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700564 {
565 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
566 int x_off = dst.left - src.left;
567 int y_off = dst.top - src.top;
568 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
569 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800570#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800571
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800572 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700573 }
574 }
575
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800576 /* No layer is updating. Still SF wants a refresh.*/
577 if(!isValidRect(roi))
578 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800579
580 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800581 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800582
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800583 ctx->listStats[mDpy].lRoi = roi;
584 if(!validateAndApplyROI(ctx, list))
585 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700586
587 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800588 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
589 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
590}
591
592void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
593 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
594 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
595
596 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
597 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
598 fbRect = getUnion(l_fbRect, r_fbRect);
599}
600/* 1) Identify layers that are not visible or lying outside BOTH the updating
601 * ROI's and drop them from composition. If a layer is spanning across both
602 * the halves of the screen but needed by only ROI, the non-contributing
603 * half will not be programmed for MDP.
604 * 2) If we have a scaling layer which needs cropping against generated
605 * ROI, reset ROI to full resolution. */
606bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
607 hwc_display_contents_1_t* list) {
608
609 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
610
611 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
612 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
613
614 for(int i = numAppLayers - 1; i >= 0; i--){
615 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
616 {
617 mCurrentFrame.drop[i] = true;
618 mCurrentFrame.dropCount++;
619 continue;
620 }
621
622 const hwc_layer_1_t* layer = &list->hwLayers[i];
623 hwc_rect_t dstRect = layer->displayFrame;
624
625 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
626 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
627 hwc_rect_t res = getUnion(l_res, r_res);
628
629 if(!isValidRect(l_res) && !isValidRect(r_res)) {
630 mCurrentFrame.drop[i] = true;
631 mCurrentFrame.dropCount++;
632 } else {
633 /* Reset frame ROI when any layer which needs scaling also needs ROI
634 * cropping */
635 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
636 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
637 mCurrentFrame.dropCount = 0;
638 return false;
639 }
640
641 if (layer->blending == HWC_BLENDING_NONE) {
642 visibleRectL = deductRect(visibleRectL, l_res);
643 visibleRectR = deductRect(visibleRectR, r_res);
644 }
645 }
646 }
647 return true;
648}
649/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
650 * are updating. If DirtyRegion is applicable, calculate it by accounting all
651 * the changing layer's dirtyRegion. */
652void MDPCompSplit::generateROI(hwc_context_t *ctx,
653 hwc_display_contents_1_t* list) {
654 if(!canPartialUpdate(ctx, list))
655 return;
656
657 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
658 int lSplit = getLeftSplit(ctx, mDpy);
659
660 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
661 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
662
663 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
664 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
665
666 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
667 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
668
669 for(int index = 0; index < numAppLayers; index++ ) {
670 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800671 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800672 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800673 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700674 hwc_rect_t dst = layer->displayFrame;
675 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800676
677#ifdef QCOM_BSP
678 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700679 {
680 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
681 int x_off = dst.left - src.left;
682 int y_off = dst.top - src.top;
683 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
684 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800685#endif
686
687 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
688 if(isValidRect(l_dst))
689 l_roi = getUnion(l_roi, l_dst);
690
691 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
692 if(isValidRect(r_dst))
693 r_roi = getUnion(r_roi, r_dst);
694 }
695 }
696
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700697 /* For panels that cannot accept commands in both the interfaces, we cannot
698 * send two ROI's (for each half). We merge them into single ROI and split
699 * them across lSplit for MDP mixer use. The ROI's will be merged again
700 * finally before udpating the panel in the driver. */
701 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
702 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
703 l_roi = getIntersection(temp_roi, l_frame);
704 r_roi = getIntersection(temp_roi, r_frame);
705 }
706
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800707 /* No layer is updating. Still SF wants a refresh. */
708 if(!isValidRect(l_roi) && !isValidRect(r_roi))
709 return;
710
711 l_roi = getSanitizeROI(l_roi, l_frame);
712 r_roi = getSanitizeROI(r_roi, r_frame);
713
714 ctx->listStats[mDpy].lRoi = l_roi;
715 ctx->listStats[mDpy].rRoi = r_roi;
716
717 if(!validateAndApplyROI(ctx, list))
718 resetROI(ctx, mDpy);
719
720 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
721 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
722 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
723 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
724 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
725 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700726}
727
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800728/* Checks for conditions where all the layers marked for MDP comp cannot be
729 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800730bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800731 hwc_display_contents_1_t* list){
732
Saurabh Shahaa236822013-04-24 18:07:26 -0700733 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800734 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800735
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700736 // Fall back to video only composition, if AIV video mode is enabled
737 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700738 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
739 __FUNCTION__, mDpy);
740 return false;
741 }
742
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400743 // No Idle fall back, if secure display or secure RGB layers are present or
744 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700745 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400746 !ctx->listStats[mDpy].secureRGBCount) &&
747 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700748 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
749 return false;
750 }
751
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800752 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700753 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
754 __FUNCTION__,
755 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800756 return false;
757 }
758
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700759 // if secondary is configuring or Padding round, fall back to video only
760 // composition and release all assigned non VIG pipes from primary.
761 if(isSecondaryConfiguring(ctx)) {
762 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
763 __FUNCTION__);
764 return false;
765 } else if(ctx->isPaddingRound) {
766 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
767 __FUNCTION__,mDpy);
768 return false;
769 }
770
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530771 MDPVersion& mdpHw = MDPVersion::getInstance();
772 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400773 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530774 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800775 // Disable MDP comp on Secondary when the primary is highres panel and
776 // the secondary is a normal 1080p, because, MDP comp on secondary under
777 // in such usecase, decimation gets used for downscale and there will be
778 // a quality mismatch when there will be a fallback to GPU comp
779 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
780 __FUNCTION__);
781 return false;
782 }
783
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700784 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800785 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700786 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800787 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
788 return false;
789 }
790
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800791 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800792 hwc_layer_1_t* layer = &list->hwLayers[i];
793 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800794
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800795 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700796 if(!canUseRotator(ctx, mDpy)) {
797 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
798 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700799 return false;
800 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800801 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530802
803 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
804 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700805 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530806 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
807 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
808 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800809 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700810
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700811 if(ctx->mAD->isDoable()) {
812 return false;
813 }
814
Saurabh Shahaa236822013-04-24 18:07:26 -0700815 //If all above hard conditions are met we can do full or partial MDP comp.
816 bool ret = false;
817 if(fullMDPComp(ctx, list)) {
818 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700819 } else if(fullMDPCompWithPTOR(ctx, list)) {
820 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700821 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700822 ret = true;
823 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530824
Saurabh Shahaa236822013-04-24 18:07:26 -0700825 return ret;
826}
827
828bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700829
830 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
831 return false;
832
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700833 //Will benefit presentation / secondary-only layer.
834 if((mDpy > HWC_DISPLAY_PRIMARY) &&
835 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
836 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
837 return false;
838 }
839
840 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
841 for(int i = 0; i < numAppLayers; i++) {
842 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700843 if(not mCurrentFrame.drop[i] and
844 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700845 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
846 return false;
847 }
848 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800849
Saurabh Shahaa236822013-04-24 18:07:26 -0700850 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700851 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
852 sizeof(mCurrentFrame.isFBComposed));
853 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
854 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700855
Raj Kamal389d6e32014-08-04 14:43:24 +0530856 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800857 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530858 }
859
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800860 if(!postHeuristicsHandling(ctx, list)) {
861 ALOGD_IF(isDebug(), "post heuristic handling failed");
862 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700863 return false;
864 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700865 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
866 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700867 return true;
868}
869
Sushil Chauhandefd3522014-05-13 18:17:12 -0700870/* Full MDP Composition with Peripheral Tiny Overlap Removal.
871 * MDP bandwidth limitations can be avoided, if the overlap region
872 * covered by the smallest layer at a higher z-order, gets composed
873 * by Copybit on a render buffer, which can be queued to MDP.
874 */
875bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
876 hwc_display_contents_1_t* list) {
877
878 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
879 const int stagesForMDP = min(sMaxPipesPerMixer,
880 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
881
882 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700883 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700884 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
885 return false;
886 }
887
888 // Frame level checks
889 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
890 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
891 isSecurePresent(ctx, mDpy)) {
892 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
893 return false;
894 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700895 // MDP comp checks
896 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700897 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700898 if(not isSupportedForMDPComp(ctx, layer)) {
899 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
900 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700901 }
902 }
903
Sushil Chauhandefd3522014-05-13 18:17:12 -0700904 /* We cannot use this composition mode, if:
905 1. A below layer needs scaling.
906 2. Overlap is not peripheral to display.
907 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700908 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700909 */
910
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700911 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
912 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
913 memset(overlapRect, 0, sizeof(overlapRect));
914 int layerPixelCount, minPixelCount = 0;
915 int numPTORLayersFound = 0;
916 for (int i = numAppLayers-1; (i >= 0 &&
917 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700918 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700919 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700920 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700921 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
922 // PTOR layer should be peripheral and cannot have transform
923 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
924 has90Transform(layer)) {
925 continue;
926 }
927 if((3 * (layerPixelCount + minPixelCount)) >
928 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
929 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
930 continue;
931 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700932 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700933 for (int j = i-1; j >= 0; j--) {
934 // Check if the layers below this layer qualifies for PTOR comp
935 hwc_layer_1_t* layer = &list->hwLayers[j];
936 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700937 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700938 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700939 if (isValidRect(getIntersection(dispFrame, disFrame))) {
940 if (has90Transform(layer) || needsScaling(layer)) {
941 found = false;
942 break;
943 }
944 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700945 }
946 }
947 // Store the minLayer Index
948 if(found) {
949 minLayerIndex[numPTORLayersFound] = i;
950 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
951 minPixelCount += layerPixelCount;
952 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700953 }
954 }
955
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700956 // No overlap layers
957 if (!numPTORLayersFound)
958 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700959
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700960 // Store the displayFrame and the sourceCrops of the layers
961 hwc_rect_t displayFrame[numAppLayers];
962 hwc_rect_t sourceCrop[numAppLayers];
963 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700964 hwc_layer_1_t* layer = &list->hwLayers[i];
965 displayFrame[i] = layer->displayFrame;
966 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700967 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700968
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530969 /**
970 * It's possible that 2 PTOR layers might have overlapping.
971 * In such case, remove the intersection(again if peripheral)
972 * from the lower PTOR layer to avoid overlapping.
973 * If intersection is not on peripheral then compromise
974 * by reducing number of PTOR layers.
975 **/
976 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
977 if(isValidRect(commonRect)) {
978 overlapRect[1] = deductRect(overlapRect[1], commonRect);
979 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
980 }
981
982 ctx->mPtorInfo.count = numPTORLayersFound;
983 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
984 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
985 }
986
987 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
988 // reset PTOR
989 ctx->mPtorInfo.count = 0;
990 if(isValidRect(commonRect)) {
991 // If PTORs are intersecting restore displayframe of PTOR[1]
992 // before returning, as we have modified it above.
993 list->hwLayers[minLayerIndex[1]].displayFrame =
994 displayFrame[minLayerIndex[1]];
995 }
996 return false;
997 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700998 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
999 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1000
Xu Yangcda012c2014-07-30 21:57:21 +08001001 // Store the blending mode, planeAlpha, and transform of PTOR layers
1002 int32_t blending[numPTORLayersFound];
1003 uint8_t planeAlpha[numPTORLayersFound];
1004 uint32_t transform[numPTORLayersFound];
1005
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001006 for(int j = 0; j < numPTORLayersFound; j++) {
1007 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001008
1009 // Update src crop of PTOR layer
1010 hwc_layer_1_t* layer = &list->hwLayers[index];
1011 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1012 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1013 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1014 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1015
1016 // Store & update w, h, format of PTOR layer
1017 private_handle_t *hnd = (private_handle_t *)layer->handle;
1018 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1019 layerWhf[j] = whf;
1020 hnd->width = renderBuf->width;
1021 hnd->height = renderBuf->height;
1022 hnd->format = renderBuf->format;
1023
Xu Yangcda012c2014-07-30 21:57:21 +08001024 // Store & update blending mode, planeAlpha and transform of PTOR layer
1025 blending[j] = layer->blending;
1026 planeAlpha[j] = layer->planeAlpha;
1027 transform[j] = layer->transform;
1028 layer->blending = HWC_BLENDING_NONE;
1029 layer->planeAlpha = 0xFF;
1030 layer->transform = 0;
1031
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001032 // Remove overlap from crop & displayFrame of below layers
1033 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001034 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001035 if(!isValidRect(getIntersection(layer->displayFrame,
1036 overlapRect[j]))) {
1037 continue;
1038 }
1039 // Update layer attributes
1040 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1041 hwc_rect_t destRect = deductRect(layer->displayFrame,
1042 overlapRect[j]);
1043 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1044 layer->transform);
1045 layer->sourceCropf.left = (float)srcCrop.left;
1046 layer->sourceCropf.top = (float)srcCrop.top;
1047 layer->sourceCropf.right = (float)srcCrop.right;
1048 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1049 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001050 }
1051
1052 mCurrentFrame.mdpCount = numAppLayers;
1053 mCurrentFrame.fbCount = 0;
1054 mCurrentFrame.fbZ = -1;
1055
1056 for (int j = 0; j < numAppLayers; j++)
1057 mCurrentFrame.isFBComposed[j] = false;
1058
1059 bool result = postHeuristicsHandling(ctx, list);
1060
1061 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001062 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001063 hwc_layer_1_t* layer = &list->hwLayers[i];
1064 layer->displayFrame = displayFrame[i];
1065 layer->sourceCropf.left = (float)sourceCrop[i].left;
1066 layer->sourceCropf.top = (float)sourceCrop[i].top;
1067 layer->sourceCropf.right = (float)sourceCrop[i].right;
1068 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1069 }
1070
Xu Yangcda012c2014-07-30 21:57:21 +08001071 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001072 for (int i = 0; i < numPTORLayersFound; i++) {
1073 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001074 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001075 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1076 hnd->width = layerWhf[i].w;
1077 hnd->height = layerWhf[i].h;
1078 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001079 layer->blending = blending[i];
1080 layer->planeAlpha = planeAlpha[i];
1081 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001082 }
1083
Sushil Chauhandefd3522014-05-13 18:17:12 -07001084 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001085 // reset PTOR
1086 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001087 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001088 } else {
1089 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1090 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001091 }
1092
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001093 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1094 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001095 return result;
1096}
1097
Saurabh Shahaa236822013-04-24 18:07:26 -07001098bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1099{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001100 if(!sEnableMixedMode) {
1101 //Mixed mode is disabled. No need to even try caching.
1102 return false;
1103 }
1104
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001105 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001106 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001107 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001108 cacheBasedComp(ctx, list);
1109 } else {
1110 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001111 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001112 }
1113
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001114 return ret;
1115}
1116
1117bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1118 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001119 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1120 return false;
1121
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001122 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001123 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001124 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001125
1126 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1127 for(int i = 0; i < numAppLayers; i++) {
1128 if(!mCurrentFrame.isFBComposed[i]) {
1129 hwc_layer_1_t* layer = &list->hwLayers[i];
1130 if(not isSupportedForMDPComp(ctx, layer)) {
1131 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1132 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001133 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001134 return false;
1135 }
1136 }
1137 }
1138
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001139 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001140 /* mark secure RGB layers for MDP comp */
1141 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301142 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001143 if(!ret) {
1144 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001145 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001146 return false;
1147 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001148
1149 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001150
Raj Kamal389d6e32014-08-04 14:43:24 +05301151 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001152 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301153 }
1154
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001155 //Will benefit cases where a video has non-updating background.
1156 if((mDpy > HWC_DISPLAY_PRIMARY) and
1157 (mdpCount > MAX_SEC_LAYERS)) {
1158 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001159 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001160 return false;
1161 }
1162
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001163 if(!postHeuristicsHandling(ctx, list)) {
1164 ALOGD_IF(isDebug(), "post heuristic handling failed");
1165 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001166 return false;
1167 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001168 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1169 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001170
Saurabh Shahaa236822013-04-24 18:07:26 -07001171 return true;
1172}
1173
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001174bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001175 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001176 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1177 return false;
1178
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001179 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001180 return false;
1181 }
1182
Saurabh Shahb772ae32013-11-18 15:40:02 -08001183 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001184 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1185 const int stagesForMDP = min(sMaxPipesPerMixer,
1186 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001187
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001188 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1189 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1190 int lastMDPSupportedIndex = numAppLayers;
1191 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001192
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001193 //Find the minimum MDP batch size
1194 for(int i = 0; i < numAppLayers;i++) {
1195 if(mCurrentFrame.drop[i]) {
1196 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001197 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001198 }
1199 hwc_layer_1_t* layer = &list->hwLayers[i];
1200 if(not isSupportedForMDPComp(ctx, layer)) {
1201 lastMDPSupportedIndex = i;
1202 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1203 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001204 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001205 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001206 }
1207
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001208 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1209 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1210 mCurrentFrame.dropCount);
1211
1212 //Start at a point where the fb batch should at least have 2 layers, for
1213 //this mode to be justified.
1214 while(fbBatchSize < 2) {
1215 ++fbBatchSize;
1216 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001217 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001218
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001219 //If there are no layers for MDP, this mode doesnt make sense.
1220 if(mdpBatchSize < 1) {
1221 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1222 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001223 return false;
1224 }
1225
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001226 mCurrentFrame.reset(numAppLayers);
1227
1228 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1229 while(mdpBatchSize > 0) {
1230 //Mark layers for MDP comp
1231 int mdpBatchLeft = mdpBatchSize;
1232 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1233 if(mCurrentFrame.drop[i]) {
1234 continue;
1235 }
1236 mCurrentFrame.isFBComposed[i] = false;
1237 --mdpBatchLeft;
1238 }
1239
1240 mCurrentFrame.fbZ = mdpBatchSize;
1241 mCurrentFrame.fbCount = fbBatchSize;
1242 mCurrentFrame.mdpCount = mdpBatchSize;
1243
1244 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1245 __FUNCTION__, mdpBatchSize, fbBatchSize,
1246 mCurrentFrame.dropCount);
1247
1248 if(postHeuristicsHandling(ctx, list)) {
1249 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001250 __FUNCTION__);
1251 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1252 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001253 return true;
1254 }
1255
1256 reset(ctx);
1257 --mdpBatchSize;
1258 ++fbBatchSize;
1259 }
1260
1261 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001262}
1263
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001264bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301265 if(mDpy or isSecurePresent(ctx, mDpy) or
1266 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001267 return false;
1268 }
1269 return true;
1270}
1271
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001272bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1273 hwc_display_contents_1_t* list){
1274 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1275 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1276 mDpy ) {
1277 return false;
1278 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001279 if(ctx->listStats[mDpy].secureUI)
1280 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001281 return true;
1282}
1283
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001284bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1285 hwc_display_contents_1_t* list) {
1286 const bool secureOnly = true;
1287 return videoOnlyComp(ctx, list, not secureOnly) or
1288 videoOnlyComp(ctx, list, secureOnly);
1289}
1290
1291bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001292 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001293 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1294 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001295 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001296
Saurabh Shahaa236822013-04-24 18:07:26 -07001297 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001298 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001299 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001300 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001301
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001302 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1303 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001304 return false;
1305 }
1306
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001307 /* Bail out if we are processing only secured video layers
1308 * and we dont have any */
1309 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001310 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001311 return false;
1312 }
1313
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001314 if(mCurrentFrame.fbCount)
1315 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001316
Raj Kamal389d6e32014-08-04 14:43:24 +05301317 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001318 adjustForSourceSplit(ctx, list);
1319 }
1320
1321 if(!postHeuristicsHandling(ctx, list)) {
1322 ALOGD_IF(isDebug(), "post heuristic handling failed");
1323 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001324 return false;
1325 }
1326
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001327 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1328 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001329 return true;
1330}
1331
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001332/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1333bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1334 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001335 // Fall back to video only composition, if AIV video mode is enabled
1336 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001337 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1338 __FUNCTION__, mDpy);
1339 return false;
1340 }
1341
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001342 const bool secureOnly = true;
1343 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1344 mdpOnlyLayersComp(ctx, list, secureOnly);
1345
1346}
1347
1348bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1349 hwc_display_contents_1_t* list, bool secureOnly) {
1350
1351 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1352 return false;
1353
1354 /* Bail out if we are processing only secured video layers
1355 * and we dont have any */
1356 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1357 reset(ctx);
1358 return false;
1359 }
1360
1361 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1362 mCurrentFrame.reset(numAppLayers);
1363 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1364
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001365 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001366 /* mark secure RGB layers for MDP comp */
1367 updateSecureRGB(ctx, list);
1368
1369 if(mCurrentFrame.mdpCount == 0) {
1370 reset(ctx);
1371 return false;
1372 }
1373
1374 /* find the maximum batch of layers to be marked for framebuffer */
1375 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1376 if(!ret) {
1377 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1378 reset(ctx);
1379 return false;
1380 }
1381
1382 if(sEnableYUVsplit){
1383 adjustForSourceSplit(ctx, list);
1384 }
1385
1386 if(!postHeuristicsHandling(ctx, list)) {
1387 ALOGD_IF(isDebug(), "post heuristic handling failed");
1388 reset(ctx);
1389 return false;
1390 }
1391
1392 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1393 __FUNCTION__);
1394 return true;
1395}
1396
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001397/* Checks for conditions where YUV layers cannot be bypassed */
1398bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001399 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001400 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001401 return false;
1402 }
1403
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001404 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001405 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1406 return false;
1407 }
1408
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001409 if(isSecuring(ctx, layer)) {
1410 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1411 return false;
1412 }
1413
Saurabh Shah4fdde762013-04-30 18:47:33 -07001414 if(!isValidDimension(ctx, layer)) {
1415 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1416 __FUNCTION__);
1417 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001418 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001419
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001420 if(layer->planeAlpha < 0xFF) {
1421 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1422 in video only mode",
1423 __FUNCTION__);
1424 return false;
1425 }
1426
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001427 return true;
1428}
1429
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001430/* Checks for conditions where Secure RGB layers cannot be bypassed */
1431bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1432 if(isSkipLayer(layer)) {
1433 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1434 __FUNCTION__, mDpy);
1435 return false;
1436 }
1437
1438 if(isSecuring(ctx, layer)) {
1439 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1440 return false;
1441 }
1442
1443 if(not isSupportedForMDPComp(ctx, layer)) {
1444 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1445 __FUNCTION__);
1446 return false;
1447 }
1448 return true;
1449}
1450
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301451/* starts at fromIndex and check for each layer to find
1452 * if it it has overlapping with any Updating layer above it in zorder
1453 * till the end of the batch. returns true if it finds any intersection */
1454bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1455 int fromIndex, int toIndex) {
1456 for(int i = fromIndex; i < toIndex; i++) {
1457 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1458 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1459 return false;
1460 }
1461 }
1462 }
1463 return true;
1464}
1465
1466/* Checks if given layer at targetLayerIndex has any
1467 * intersection with all the updating layers in beween
1468 * fromIndex and toIndex. Returns true if it finds intersectiion */
1469bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1470 int fromIndex, int toIndex, int targetLayerIndex) {
1471 for(int i = fromIndex; i <= toIndex; i++) {
1472 if(!mCurrentFrame.isFBComposed[i]) {
1473 if(areLayersIntersecting(&list->hwLayers[i],
1474 &list->hwLayers[targetLayerIndex])) {
1475 return true;
1476 }
1477 }
1478 }
1479 return false;
1480}
1481
1482int MDPComp::getBatch(hwc_display_contents_1_t* list,
1483 int& maxBatchStart, int& maxBatchEnd,
1484 int& maxBatchCount) {
1485 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301486 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001487 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301488 while (i < mCurrentFrame.layerCount) {
1489 int batchCount = 0;
1490 int batchStart = i;
1491 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001492 /* Adjust batch Z order with the dropped layers so far */
1493 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301494 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301495 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301496 while(i < mCurrentFrame.layerCount) {
1497 if(!mCurrentFrame.isFBComposed[i]) {
1498 if(!batchCount) {
1499 i++;
1500 break;
1501 }
1502 updatingLayersAbove++;
1503 i++;
1504 continue;
1505 } else {
1506 if(mCurrentFrame.drop[i]) {
1507 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001508 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301509 continue;
1510 } else if(updatingLayersAbove <= 0) {
1511 batchCount++;
1512 batchEnd = i;
1513 i++;
1514 continue;
1515 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1516
1517 // We have a valid updating layer already. If layer-i not
1518 // have overlapping with all updating layers in between
1519 // batch-start and i, then we can add layer i to batch.
1520 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1521 batchCount++;
1522 batchEnd = i;
1523 i++;
1524 continue;
1525 } else if(canPushBatchToTop(list, batchStart, i)) {
1526 //If All the non-updating layers with in this batch
1527 //does not have intersection with the updating layers
1528 //above in z-order, then we can safely move the batch to
1529 //higher z-order. Increment fbZ as it is moving up.
1530 if( firstZReverseIndex < 0) {
1531 firstZReverseIndex = i;
1532 }
1533 batchCount++;
1534 batchEnd = i;
1535 fbZ += updatingLayersAbove;
1536 i++;
1537 updatingLayersAbove = 0;
1538 continue;
1539 } else {
1540 //both failed.start the loop again from here.
1541 if(firstZReverseIndex >= 0) {
1542 i = firstZReverseIndex;
1543 }
1544 break;
1545 }
1546 }
1547 }
1548 }
1549 if(batchCount > maxBatchCount) {
1550 maxBatchCount = batchCount;
1551 maxBatchStart = batchStart;
1552 maxBatchEnd = batchEnd;
1553 fbZOrder = fbZ;
1554 }
1555 }
1556 return fbZOrder;
1557}
1558
1559bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1560 hwc_display_contents_1_t* list) {
1561 /* Idea is to keep as many non-updating(cached) layers in FB and
1562 * send rest of them through MDP. This is done in 2 steps.
1563 * 1. Find the maximum contiguous batch of non-updating layers.
1564 * 2. See if we can improve this batch size for caching by adding
1565 * opaque layers around the batch, if they don't have
1566 * any overlapping with the updating layers in between.
1567 * NEVER mark an updating layer for caching.
1568 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001569
1570 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001571 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001572 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301573 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001574
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001575 /* Nothing is cached. No batching needed */
1576 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001577 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001578 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001579
1580 /* No MDP comp layers, try to use other comp modes */
1581 if(mCurrentFrame.mdpCount == 0) {
1582 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001583 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001584
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301585 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001586
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301587 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001588 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001589 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001590 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301591 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001592 if(!mCurrentFrame.drop[i]){
1593 //If an unsupported layer is being attempted to
1594 //be pulled out we should fail
1595 if(not isSupportedForMDPComp(ctx, layer)) {
1596 return false;
1597 }
1598 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001599 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001600 }
1601 }
1602
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301603 // update the frame data
1604 mCurrentFrame.fbZ = fbZ;
1605 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001606 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001607 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608
1609 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301610 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001611
1612 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001613}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001614
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001615void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001616 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001617 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001618 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001620 for(int i = 0; i < numAppLayers; i++) {
1621 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001622 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001623 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001624 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001625 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001626 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627 }
1628 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001629
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001630 frame.fbCount = fbCount;
1631 frame.mdpCount = frame.layerCount - frame.fbCount
1632 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001633
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001634 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1635 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001636}
1637
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001638// drop other non-AIV layers from external display list.
1639void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001640 hwc_display_contents_1_t* list) {
1641 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1642 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001643 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001644 mCurrentFrame.dropCount++;
1645 mCurrentFrame.drop[i] = true;
1646 }
1647 }
1648 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1649 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1650 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1651 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1652 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1653 mCurrentFrame.dropCount);
1654}
1655
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001656void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001657 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001658 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1659 for(int index = 0;index < nYuvCount; index++){
1660 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1661 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1662
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001663 if(mCurrentFrame.drop[nYuvIndex]) {
1664 continue;
1665 }
1666
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001667 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001668 if(!frame.isFBComposed[nYuvIndex]) {
1669 frame.isFBComposed[nYuvIndex] = true;
1670 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001671 }
1672 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001673 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001674 private_handle_t *hnd = (private_handle_t *)layer->handle;
1675 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001676 frame.isFBComposed[nYuvIndex] = false;
1677 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001678 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001679 }
1680 }
1681 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001682
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001683 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1684 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001685}
1686
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001687void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1688 hwc_display_contents_1_t* list) {
1689 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1690 for(int index = 0;index < nSecureRGBCount; index++){
1691 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1692 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1693
1694 if(!isSecureRGBDoable(ctx, layer)) {
1695 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1696 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1697 mCurrentFrame.fbCount++;
1698 }
1699 } else {
1700 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1701 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1702 mCurrentFrame.fbCount--;
1703 }
1704 }
1705 }
1706
1707 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1708 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1709 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1710 mCurrentFrame.fbCount);
1711}
1712
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001713hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1714 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001715 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001716
1717 /* Update only the region of FB needed for composition */
1718 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1719 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1720 hwc_layer_1_t* layer = &list->hwLayers[i];
1721 hwc_rect_t dst = layer->displayFrame;
1722 fbRect = getUnion(fbRect, dst);
1723 }
1724 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001725 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001726 return fbRect;
1727}
1728
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001729bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1730 hwc_display_contents_1_t* list) {
1731
1732 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001733 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001734 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1735 return false;
1736 }
1737
1738 //Limitations checks
1739 if(!hwLimitationsCheck(ctx, list)) {
1740 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1741 return false;
1742 }
1743
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001744 //Configure framebuffer first if applicable
1745 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001746 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001747 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1748 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001749 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1750 __FUNCTION__);
1751 return false;
1752 }
1753 }
1754
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001755 mCurrentFrame.map();
1756
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001757 if(!allocLayerPipes(ctx, list)) {
1758 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001759 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001760 }
1761
1762 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001763 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001764 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001765 int mdpIndex = mCurrentFrame.layerToMDP[index];
1766 hwc_layer_1_t* layer = &list->hwLayers[index];
1767
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301768 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1769 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1770 mdpNextZOrder++;
1771 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001772 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1773 cur_pipe->zOrder = mdpNextZOrder++;
1774
radhakrishnac9a67412013-09-25 17:40:42 +05301775 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301776 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301777 if(configure4k2kYuv(ctx, layer,
1778 mCurrentFrame.mdpToLayer[mdpIndex])
1779 != 0 ){
1780 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1781 for layer %d",__FUNCTION__, index);
1782 return false;
1783 }
1784 else{
1785 mdpNextZOrder++;
1786 }
1787 continue;
1788 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001789 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1790 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301791 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001792 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001793 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001794 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001795 }
1796
Saurabh Shaha36be922013-12-16 18:18:39 -08001797 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1798 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1799 ,__FUNCTION__, mDpy);
1800 return false;
1801 }
1802
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001803 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001804 return true;
1805}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001806
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001807bool MDPComp::resourceCheck(hwc_context_t* ctx,
1808 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001809 const bool fbUsed = mCurrentFrame.fbCount;
1810 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1811 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1812 return false;
1813 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001814 // Init rotCount to number of rotate sessions used by other displays
1815 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1816 // Count the number of rotator sessions required for current display
1817 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1818 if(!mCurrentFrame.isFBComposed[index]) {
1819 hwc_layer_1_t* layer = &list->hwLayers[index];
1820 private_handle_t *hnd = (private_handle_t *)layer->handle;
1821 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1822 rotCount++;
1823 }
1824 }
1825 }
1826 // if number of layers to rotate exceeds max rotator sessions, bail out.
1827 if(rotCount > RotMgr::MAX_ROT_SESS) {
1828 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1829 __FUNCTION__, mDpy);
1830 return false;
1831 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001832 return true;
1833}
1834
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301835bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1836 hwc_display_contents_1_t* list) {
1837
1838 //A-family hw limitation:
1839 //If a layer need alpha scaling, MDP can not support.
1840 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1841 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1842 if(!mCurrentFrame.isFBComposed[i] &&
1843 isAlphaScaled( &list->hwLayers[i])) {
1844 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1845 return false;
1846 }
1847 }
1848 }
1849
1850 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1851 //If multiple layers requires downscaling and also they are overlapping
1852 //fall back to GPU since MDSS can not handle it.
1853 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1854 qdutils::MDPVersion::getInstance().is8x26()) {
1855 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1856 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1857 if(!mCurrentFrame.isFBComposed[i] &&
1858 isDownscaleRequired(botLayer)) {
1859 //if layer-i is marked for MDP and needs downscaling
1860 //check if any MDP layer on top of i & overlaps with layer-i
1861 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1862 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1863 if(!mCurrentFrame.isFBComposed[j] &&
1864 isDownscaleRequired(topLayer)) {
1865 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1866 topLayer->displayFrame);
1867 if(isValidRect(r))
1868 return false;
1869 }
1870 }
1871 }
1872 }
1873 }
1874 return true;
1875}
1876
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001877int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001878 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001879 char property[PROPERTY_VALUE_MAX];
1880
Raj Kamal4393eaa2014-06-06 13:45:20 +05301881 if(!ctx || !list) {
1882 ALOGE("%s: Invalid context or list",__FUNCTION__);
1883 mCachedFrame.reset();
1884 return -1;
1885 }
1886
1887 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001888 if(mDpy == HWC_DISPLAY_PRIMARY) {
1889 sSimulationFlags = 0;
1890 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1891 int currentFlags = atoi(property);
1892 if(currentFlags != sSimulationFlags) {
1893 sSimulationFlags = currentFlags;
1894 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1895 sSimulationFlags, sSimulationFlags);
1896 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001897 }
1898 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001899 // reset PTOR
1900 if(!mDpy)
1901 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001902
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301903 //Do not cache the information for next draw cycle.
1904 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1905 ALOGI("%s: Unsupported layer count for mdp composition",
1906 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001907 mCachedFrame.reset();
1908 return -1;
1909 }
1910
Saurabh Shahb39f8152013-08-22 10:21:44 -07001911 //reset old data
1912 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001913 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1914 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301915
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001916 // Detect the start of animation and fall back to GPU only once to cache
1917 // all the layers in FB and display FB content untill animation completes.
1918 if(ctx->listStats[mDpy].isDisplayAnimating) {
1919 mCurrentFrame.needsRedraw = false;
1920 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1921 mCurrentFrame.needsRedraw = true;
1922 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1923 }
1924 setMDPCompLayerFlags(ctx, list);
1925 mCachedFrame.updateCounts(mCurrentFrame);
1926 ret = -1;
1927 return ret;
1928 } else {
1929 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1930 }
1931
Saurabh Shahb39f8152013-08-22 10:21:44 -07001932 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001933 if(isFrameDoable(ctx)) {
1934 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001935 // if AIV Video mode is enabled, drop all non AIV layers from the
1936 // external display list.
1937 if(ctx->listStats[mDpy].mAIVVideoMode) {
1938 dropNonAIVLayers(ctx, list);
1939 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001940
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001941 // if tryFullFrame fails, try to push all video and secure RGB layers
1942 // to MDP for composition.
1943 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001944 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301945 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001946 setMDPCompLayerFlags(ctx, list);
1947 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001948 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001949 reset(ctx);
1950 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1951 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001952 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001953 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1954 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001955 }
1956 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301957 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1958 enablePartialUpdateForMDP3) {
1959 generateROI(ctx, list);
1960 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1961 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1962 }
1963 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001964 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1965 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001966 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001967 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001968
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001969 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001970 ALOGD("GEOMETRY change: %d",
1971 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001972 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001973 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001974 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001975 }
1976
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001977#ifdef DYNAMIC_FPS
1978 //For primary display, set the dynamic refreshrate
1979 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1980 FrameInfo frame;
1981 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301982 memset(&frame.drop, 0, sizeof(frame.drop));
1983 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001984 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1985 __FUNCTION__);
1986 updateLayerCache(ctx, list, frame);
1987 updateYUV(ctx, list, false /*secure only*/, frame);
1988 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1989 //Set the new fresh rate, if there is only one updating YUV layer
1990 //or there is one single RGB layer with this request
1991 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1992 (frame.layerCount == 1)) {
1993 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1994 }
1995 setRefreshRate(ctx, mDpy, refreshRate);
1996 }
1997#endif
1998
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001999 mCachedFrame.cacheAll(list);
2000 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002001 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002002}
2003
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002004bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302005
2006 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302007 int mdpIndex = mCurrentFrame.layerToMDP[index];
2008 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2009 info.pipeInfo = new MdpYUVPipeInfo;
2010 info.rot = NULL;
2011 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302012
2013 pipe_info.lIndex = ovutils::OV_INVALID;
2014 pipe_info.rIndex = ovutils::OV_INVALID;
2015
Saurabh Shahc62f3982014-03-05 14:28:26 -08002016 Overlay::PipeSpecs pipeSpecs;
2017 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2018 pipeSpecs.needsScaling = true;
2019 pipeSpecs.dpy = mDpy;
2020 pipeSpecs.fb = false;
2021
2022 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302023 if(pipe_info.lIndex == ovutils::OV_INVALID){
2024 bRet = false;
2025 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2026 __FUNCTION__);
2027 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002028 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302029 if(pipe_info.rIndex == ovutils::OV_INVALID){
2030 bRet = false;
2031 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2032 __FUNCTION__);
2033 }
2034 return bRet;
2035}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002036
2037int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2038 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002039 if (ctx->mPtorInfo.isActive()) {
2040 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002041 if (fd < 0) {
2042 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002043 }
2044 }
2045 return fd;
2046}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002047//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002048
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002049void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302050 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002051 //If 4k2k Yuv layer split is possible, and if
2052 //fbz is above 4k2k layer, increment fb zorder by 1
2053 //as we split 4k2k layer and increment zorder for right half
2054 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002055 if(!ctx)
2056 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002057 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302058 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2059 index++) {
2060 if(!mCurrentFrame.isFBComposed[index]) {
2061 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2062 mdpNextZOrder++;
2063 }
2064 mdpNextZOrder++;
2065 hwc_layer_1_t* layer = &list->hwLayers[index];
2066 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302067 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302068 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2069 mCurrentFrame.fbZ += 1;
2070 mdpNextZOrder++;
2071 //As we split 4kx2k yuv layer and program to 2 VG pipes
2072 //(if available) increase mdpcount by 1.
2073 mCurrentFrame.mdpCount++;
2074 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002075 }
2076 }
2077 }
radhakrishnac9a67412013-09-25 17:40:42 +05302078}
2079
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002080/*
2081 * Configures pipe(s) for MDP composition
2082 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002083int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002084 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002085 MdpPipeInfoNonSplit& mdp_info =
2086 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302087 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002088 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002089 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002090
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002091 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2092 __FUNCTION__, layer, zOrder, dest);
2093
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002094 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002095 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002096}
2097
Saurabh Shah88e4d272013-09-03 13:31:29 -07002098bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002099 hwc_display_contents_1_t* list) {
2100 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002101
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002102 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002103
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002104 hwc_layer_1_t* layer = &list->hwLayers[index];
2105 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302106 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002107 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302108 continue;
2109 }
2110 }
2111
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002112 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002113 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002114 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002115 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002116 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002117
Saurabh Shahc62f3982014-03-05 14:28:26 -08002118 Overlay::PipeSpecs pipeSpecs;
2119 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2120 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2121 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2122 (qdutils::MDPVersion::getInstance().is8x26() and
2123 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2124 pipeSpecs.dpy = mDpy;
2125 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002126 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002127
Saurabh Shahc62f3982014-03-05 14:28:26 -08002128 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2129
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002130 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002131 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002132 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002133 }
2134 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002135 return true;
2136}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137
radhakrishnac9a67412013-09-25 17:40:42 +05302138int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2139 PipeLayerPair& PipeLayerPair) {
2140 MdpYUVPipeInfo& mdp_info =
2141 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2142 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302143 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302144 eDest lDest = mdp_info.lIndex;
2145 eDest rDest = mdp_info.rIndex;
2146
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002147 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302148 lDest, rDest, &PipeLayerPair.rot);
2149}
2150
Saurabh Shah88e4d272013-09-03 13:31:29 -07002151bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002152
Raj Kamal4393eaa2014-06-06 13:45:20 +05302153 if(!isEnabled() or !mModeOn) {
2154 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302155 return true;
2156 }
2157
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002158 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002159 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002160 sHandleTimeout = true;
2161 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002162
2163 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002164 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002165
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002166 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2167 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002168 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002169 if(mCurrentFrame.isFBComposed[i]) continue;
2170
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002171 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002172 private_handle_t *hnd = (private_handle_t *)layer->handle;
2173 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002174 if (!(layer->flags & HWC_COLOR_FILL)) {
2175 ALOGE("%s handle null", __FUNCTION__);
2176 return false;
2177 }
2178 // No PLAY for Color layer
2179 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2180 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002181 }
2182
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002183 int mdpIndex = mCurrentFrame.layerToMDP[i];
2184
Raj Kamal389d6e32014-08-04 14:43:24 +05302185 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302186 {
2187 MdpYUVPipeInfo& pipe_info =
2188 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2189 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2190 ovutils::eDest indexL = pipe_info.lIndex;
2191 ovutils::eDest indexR = pipe_info.rIndex;
2192 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302193 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302194 if(rot) {
2195 rot->queueBuffer(fd, offset);
2196 fd = rot->getDstMemId();
2197 offset = rot->getDstOffset();
2198 }
2199 if(indexL != ovutils::OV_INVALID) {
2200 ovutils::eDest destL = (ovutils::eDest)indexL;
2201 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2202 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2203 if (!ov.queueBuffer(fd, offset, destL)) {
2204 ALOGE("%s: queueBuffer failed for display:%d",
2205 __FUNCTION__, mDpy);
2206 return false;
2207 }
2208 }
2209
2210 if(indexR != ovutils::OV_INVALID) {
2211 ovutils::eDest destR = (ovutils::eDest)indexR;
2212 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2213 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2214 if (!ov.queueBuffer(fd, offset, destR)) {
2215 ALOGE("%s: queueBuffer failed for display:%d",
2216 __FUNCTION__, mDpy);
2217 return false;
2218 }
2219 }
2220 }
2221 else{
2222 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002223 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302224 ovutils::eDest dest = pipe_info.index;
2225 if(dest == ovutils::OV_INVALID) {
2226 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002227 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302228 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002229
radhakrishnac9a67412013-09-25 17:40:42 +05302230 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2231 continue;
2232 }
2233
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002234 int fd = hnd->fd;
2235 uint32_t offset = (uint32_t)hnd->offset;
2236 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2237 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002238 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002239 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002240 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002241 }
2242
radhakrishnac9a67412013-09-25 17:40:42 +05302243 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2244 using pipe: %d", __FUNCTION__, layer,
2245 hnd, dest );
2246
radhakrishnac9a67412013-09-25 17:40:42 +05302247 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2248 if(rot) {
2249 if(!rot->queueBuffer(fd, offset))
2250 return false;
2251 fd = rot->getDstMemId();
2252 offset = rot->getDstOffset();
2253 }
2254
2255 if (!ov.queueBuffer(fd, offset, dest)) {
2256 ALOGE("%s: queueBuffer failed for display:%d ",
2257 __FUNCTION__, mDpy);
2258 return false;
2259 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002260 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002261
2262 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002263 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002264 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002265}
2266
Saurabh Shah88e4d272013-09-03 13:31:29 -07002267//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002268
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002269void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302270 hwc_display_contents_1_t* list){
2271 //if 4kx2k yuv layer is totally present in either in left half
2272 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302273 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302274 if(mCurrentFrame.fbZ >= 0) {
2275 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2276 index++) {
2277 if(!mCurrentFrame.isFBComposed[index]) {
2278 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2279 mdpNextZOrder++;
2280 }
2281 mdpNextZOrder++;
2282 hwc_layer_1_t* layer = &list->hwLayers[index];
2283 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302284 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302285 hwc_rect_t dst = layer->displayFrame;
2286 if((dst.left > lSplit) || (dst.right < lSplit)) {
2287 mCurrentFrame.mdpCount += 1;
2288 }
2289 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2290 mCurrentFrame.fbZ += 1;
2291 mdpNextZOrder++;
2292 }
2293 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002294 }
radhakrishnac9a67412013-09-25 17:40:42 +05302295 }
2296}
2297
Saurabh Shah88e4d272013-09-03 13:31:29 -07002298bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002299 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002300
Saurabh Shahc62f3982014-03-05 14:28:26 -08002301 const int lSplit = getLeftSplit(ctx, mDpy);
2302 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002303 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002304 pipe_info.lIndex = ovutils::OV_INVALID;
2305 pipe_info.rIndex = ovutils::OV_INVALID;
2306
Saurabh Shahc62f3982014-03-05 14:28:26 -08002307 Overlay::PipeSpecs pipeSpecs;
2308 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2309 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2310 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2311 pipeSpecs.dpy = mDpy;
2312 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2313 pipeSpecs.fb = false;
2314
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002315 // Acquire pipe only for the updating half
2316 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2317 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2318
2319 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002320 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002321 if(pipe_info.lIndex == ovutils::OV_INVALID)
2322 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002323 }
2324
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002325 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002326 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2327 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002328 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002329 return false;
2330 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002331
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002332 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002333}
2334
Saurabh Shah88e4d272013-09-03 13:31:29 -07002335bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002336 hwc_display_contents_1_t* list) {
2337 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002338
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002339 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002340
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002341 hwc_layer_1_t* layer = &list->hwLayers[index];
2342 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302343 hwc_rect_t dst = layer->displayFrame;
2344 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302345 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302346 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002347 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302348 continue;
2349 }
2350 }
2351 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002352 int mdpIndex = mCurrentFrame.layerToMDP[index];
2353 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002354 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002355 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002356 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002357
Saurabh Shahc62f3982014-03-05 14:28:26 -08002358 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2359 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2360 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002361 return false;
2362 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002363 }
2364 return true;
2365}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002366
radhakrishnac9a67412013-09-25 17:40:42 +05302367int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2368 PipeLayerPair& PipeLayerPair) {
2369 const int lSplit = getLeftSplit(ctx, mDpy);
2370 hwc_rect_t dst = layer->displayFrame;
2371 if((dst.left > lSplit)||(dst.right < lSplit)){
2372 MdpYUVPipeInfo& mdp_info =
2373 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2374 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302375 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302376 eDest lDest = mdp_info.lIndex;
2377 eDest rDest = mdp_info.rIndex;
2378
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002379 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302380 lDest, rDest, &PipeLayerPair.rot);
2381 }
2382 else{
2383 return configure(ctx, layer, PipeLayerPair);
2384 }
2385}
2386
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002387/*
2388 * Configures pipe(s) for MDP composition
2389 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002390int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002391 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002392 MdpPipeInfoSplit& mdp_info =
2393 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002394 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302395 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002396 eDest lDest = mdp_info.lIndex;
2397 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002398
2399 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2400 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2401
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002402 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002403 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002404}
2405
Saurabh Shah88e4d272013-09-03 13:31:29 -07002406bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002407
Raj Kamal4393eaa2014-06-06 13:45:20 +05302408 if(!isEnabled() or !mModeOn) {
2409 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302410 return true;
2411 }
2412
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002413 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002414 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002415 sHandleTimeout = true;
2416 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002417
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002418 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002419 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002420
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002421 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2422 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002423 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002424 if(mCurrentFrame.isFBComposed[i]) continue;
2425
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002426 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002427 private_handle_t *hnd = (private_handle_t *)layer->handle;
2428 if(!hnd) {
2429 ALOGE("%s handle null", __FUNCTION__);
2430 return false;
2431 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002432
2433 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2434 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002435 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002436
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002437 int mdpIndex = mCurrentFrame.layerToMDP[i];
2438
Raj Kamal389d6e32014-08-04 14:43:24 +05302439 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302440 {
2441 MdpYUVPipeInfo& pipe_info =
2442 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2443 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2444 ovutils::eDest indexL = pipe_info.lIndex;
2445 ovutils::eDest indexR = pipe_info.rIndex;
2446 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302447 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302448 if(rot) {
2449 rot->queueBuffer(fd, offset);
2450 fd = rot->getDstMemId();
2451 offset = rot->getDstOffset();
2452 }
2453 if(indexL != ovutils::OV_INVALID) {
2454 ovutils::eDest destL = (ovutils::eDest)indexL;
2455 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2456 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2457 if (!ov.queueBuffer(fd, offset, destL)) {
2458 ALOGE("%s: queueBuffer failed for display:%d",
2459 __FUNCTION__, mDpy);
2460 return false;
2461 }
2462 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002463
radhakrishnac9a67412013-09-25 17:40:42 +05302464 if(indexR != ovutils::OV_INVALID) {
2465 ovutils::eDest destR = (ovutils::eDest)indexR;
2466 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2467 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2468 if (!ov.queueBuffer(fd, offset, destR)) {
2469 ALOGE("%s: queueBuffer failed for display:%d",
2470 __FUNCTION__, mDpy);
2471 return false;
2472 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002473 }
2474 }
radhakrishnac9a67412013-09-25 17:40:42 +05302475 else{
2476 MdpPipeInfoSplit& pipe_info =
2477 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2478 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002479
radhakrishnac9a67412013-09-25 17:40:42 +05302480 ovutils::eDest indexL = pipe_info.lIndex;
2481 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002482
radhakrishnac9a67412013-09-25 17:40:42 +05302483 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002484 uint32_t offset = (uint32_t)hnd->offset;
2485 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2486 if (!mDpy && (index != -1)) {
2487 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2488 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002489 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002490 }
radhakrishnac9a67412013-09-25 17:40:42 +05302491
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002492 if(ctx->mAD->draw(ctx, fd, offset)) {
2493 fd = ctx->mAD->getDstFd();
2494 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002495 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002496
radhakrishnac9a67412013-09-25 17:40:42 +05302497 if(rot) {
2498 rot->queueBuffer(fd, offset);
2499 fd = rot->getDstMemId();
2500 offset = rot->getDstOffset();
2501 }
2502
2503 //************* play left mixer **********
2504 if(indexL != ovutils::OV_INVALID) {
2505 ovutils::eDest destL = (ovutils::eDest)indexL;
2506 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2507 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2508 if (!ov.queueBuffer(fd, offset, destL)) {
2509 ALOGE("%s: queueBuffer failed for left mixer",
2510 __FUNCTION__);
2511 return false;
2512 }
2513 }
2514
2515 //************* play right mixer **********
2516 if(indexR != ovutils::OV_INVALID) {
2517 ovutils::eDest destR = (ovutils::eDest)indexR;
2518 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2519 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2520 if (!ov.queueBuffer(fd, offset, destR)) {
2521 ALOGE("%s: queueBuffer failed for right mixer",
2522 __FUNCTION__);
2523 return false;
2524 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002525 }
2526 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002527
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002528 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2529 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002530
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002531 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002532}
Saurabh Shahab47c692014-02-12 18:45:57 -08002533
2534//================MDPCompSrcSplit==============================================
2535bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002536 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002537 private_handle_t *hnd = (private_handle_t *)layer->handle;
2538 hwc_rect_t dst = layer->displayFrame;
2539 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2540 pipe_info.lIndex = ovutils::OV_INVALID;
2541 pipe_info.rIndex = ovutils::OV_INVALID;
2542
2543 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2544 //should have a higher priority than the right one. Pipe priorities are
2545 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002546
Saurabh Shahc62f3982014-03-05 14:28:26 -08002547 Overlay::PipeSpecs pipeSpecs;
2548 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2549 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2550 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2551 pipeSpecs.dpy = mDpy;
2552 pipeSpecs.fb = false;
2553
Saurabh Shahab47c692014-02-12 18:45:57 -08002554 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002555 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002556 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002557 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002558 }
2559
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002560 /* Use 2 pipes IF
2561 a) Layer's crop width is > 2048 or
2562 b) Layer's dest width > 2048 or
2563 c) On primary, driver has indicated with caps to split always. This is
2564 based on an empirically derived value of panel height. Applied only
2565 if the layer's width is > mixer's width
2566 */
2567
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302568 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002569 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302570 mdpHw.isSrcSplitAlways();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002571 int lSplit = getLeftSplit(ctx, mDpy);
2572 int dstWidth = dst.right - dst.left;
Saurabh Shah189f23d2014-09-26 17:21:00 -07002573 int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2574 crop.right - crop.left;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002575
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002576 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2577 //pipe line length, we are still using 2 pipes. This is fine just because
2578 //this is source split where destination doesn't matter. Evaluate later to
2579 //see if going through all the calcs to save a pipe is worth it
Naseer Ahmed9eb5e092014-09-25 13:24:44 -04002580 if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
2581 cropWidth > (int) mdpHw.getMaxMixerWidth() or
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002582 (primarySplitAlways and (cropWidth > lSplit))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002583 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002584 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002585 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002586 }
2587
2588 // Return values
2589 // 1 Left pipe is higher priority, do nothing.
2590 // 0 Pipes of same priority.
2591 //-1 Right pipe is of higher priority, needs swap.
2592 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2593 pipe_info.rIndex) == -1) {
2594 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002595 }
2596 }
2597
2598 return true;
2599}
2600
Saurabh Shahab47c692014-02-12 18:45:57 -08002601int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2602 PipeLayerPair& PipeLayerPair) {
2603 private_handle_t *hnd = (private_handle_t *)layer->handle;
2604 if(!hnd) {
2605 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2606 return -1;
2607 }
2608 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2609 MdpPipeInfoSplit& mdp_info =
2610 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2611 Rotator **rot = &PipeLayerPair.rot;
2612 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002613 eDest lDest = mdp_info.lIndex;
2614 eDest rDest = mdp_info.rIndex;
2615 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2616 hwc_rect_t dst = layer->displayFrame;
2617 int transform = layer->transform;
2618 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002619 int rotFlags = ROT_FLAGS_NONE;
2620 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2621 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2622
2623 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2624 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2625
2626 // Handle R/B swap
2627 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2628 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2629 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2630 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2631 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2632 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002633 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002634 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2635 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002636 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002637 /* Calculate the external display position based on MDP downscale,
2638 ActionSafe, and extorientation features. */
2639 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002640
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002641 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302642 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002643 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002644
2645 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2646 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002647 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002648 }
2649
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002650 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002651 (*rot) = ctx->mRotMgr->getNext();
2652 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002653 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002654 //If the video is using a single pipe, enable BWC
2655 if(rDest == OV_INVALID) {
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002656 BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002657 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002658 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002659 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002660 ALOGE("%s: configRotator failed!", __FUNCTION__);
2661 return -1;
2662 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002663 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002664 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002665 }
2666
2667 //If 2 pipes being used, divide layer into half, crop and dst
2668 hwc_rect_t cropL = crop;
2669 hwc_rect_t cropR = crop;
2670 hwc_rect_t dstL = dst;
2671 hwc_rect_t dstR = dst;
2672 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2673 cropL.right = (crop.right + crop.left) / 2;
2674 cropR.left = cropL.right;
2675 sanitizeSourceCrop(cropL, cropR, hnd);
2676
Saurabh Shahb729b192014-08-15 18:04:24 -07002677 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002678 //Swap crops on H flip since 2 pipes are being used
2679 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2680 hwc_rect_t tmp = cropL;
2681 cropL = cropR;
2682 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002683 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002684 }
2685
Saurabh Shahb729b192014-08-15 18:04:24 -07002686 //cropSwap trick: If the src and dst widths are both odd, let us say
2687 //2507, then splitting both into half would cause left width to be 1253
2688 //and right 1254. If crop is swapped because of H flip, this will cause
2689 //left crop width to be 1254, whereas left dst width remains 1253, thus
2690 //inducing a scaling that is unaccounted for. To overcome that we add 1
2691 //to the dst width if there is a cropSwap. So if the original width was
2692 //2507, the left dst width will be 1254. Even if the original width was
2693 //even for ex: 2508, the left dst width will still remain 1254.
2694 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002695 dstR.left = dstL.right;
2696 }
2697
2698 //For the mdp, since either we are pre-rotating or MDP does flips
2699 orient = OVERLAY_TRANSFORM_0;
2700 transform = 0;
2701
2702 //configure left pipe
2703 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002704 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002705 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2706 (ovutils::eBlending) getBlending(layer->blending));
2707
2708 if(configMdp(ctx->mOverlay, pargL, orient,
2709 cropL, dstL, metadata, lDest) < 0) {
2710 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2711 return -1;
2712 }
2713 }
2714
2715 //configure right pipe
2716 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002717 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002718 static_cast<eRotFlags>(rotFlags),
2719 layer->planeAlpha,
2720 (ovutils::eBlending) getBlending(layer->blending));
2721 if(configMdp(ctx->mOverlay, pargR, orient,
2722 cropR, dstR, metadata, rDest) < 0) {
2723 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2724 return -1;
2725 }
2726 }
2727
2728 return 0;
2729}
2730
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002731}; //namespace
2732