blob: aa7783cea08fc75d742da082d390f3755ce1c708 [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 */
radhakrishna4efbdd62014-11-03 13:19:27 +0530535 if (layer->blending == HWC_BLENDING_NONE &&
536 layer->planeAlpha == 0xFF)
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800537 visibleRect = deductRect(visibleRect, res);
538 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700539 }
540 return true;
541}
542
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800543/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
544 * are updating. If DirtyRegion is applicable, calculate it by accounting all
545 * the changing layer's dirtyRegion. */
546void MDPCompNonSplit::generateROI(hwc_context_t *ctx,
547 hwc_display_contents_1_t* list) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700548 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800549 if(!canPartialUpdate(ctx, list))
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700550 return;
551
552 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800553 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
554 (int)ctx->dpyAttr[mDpy].yres};
555
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700556 for(int index = 0; index < numAppLayers; index++ ) {
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800557 hwc_layer_1_t* layer = &list->hwLayers[index];
558 if ((mCachedFrame.hnd[index] != layer->handle) ||
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800559 isYuvBuffer((private_handle_t *)layer->handle)) {
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700560 hwc_rect_t dst = layer->displayFrame;
561 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800562
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800563#ifdef QCOM_BSP
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800564 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran455678c2014-05-30 10:22:38 -0700565 {
566 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
567 int x_off = dst.left - src.left;
568 int y_off = dst.top - src.top;
569 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
570 }
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800571#endif
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800572
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800573 roi = getUnion(roi, updatingRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700574 }
575 }
576
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800577 /* No layer is updating. Still SF wants a refresh.*/
578 if(!isValidRect(roi))
579 return;
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800580
581 // Align ROI coordinates to panel restrictions
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800582 roi = getSanitizeROI(roi, fullFrame);
Jeykumar Sankaran7c852382014-02-26 18:26:58 -0800583
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800584 ctx->listStats[mDpy].lRoi = roi;
585 if(!validateAndApplyROI(ctx, list))
586 resetROI(ctx, mDpy);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700587
588 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800589 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
590 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
591}
592
593void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) {
594 hwc_rect l_roi = ctx->listStats[mDpy].lRoi;
595 hwc_rect r_roi = ctx->listStats[mDpy].rRoi;
596
597 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi);
598 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi);
599 fbRect = getUnion(l_fbRect, r_fbRect);
600}
601/* 1) Identify layers that are not visible or lying outside BOTH the updating
602 * ROI's and drop them from composition. If a layer is spanning across both
603 * the halves of the screen but needed by only ROI, the non-contributing
604 * half will not be programmed for MDP.
605 * 2) If we have a scaling layer which needs cropping against generated
606 * ROI, reset ROI to full resolution. */
607bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
608 hwc_display_contents_1_t* list) {
609
610 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
611
612 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
613 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
614
615 for(int i = numAppLayers - 1; i >= 0; i--){
616 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
617 {
618 mCurrentFrame.drop[i] = true;
619 mCurrentFrame.dropCount++;
620 continue;
621 }
622
623 const hwc_layer_1_t* layer = &list->hwLayers[i];
624 hwc_rect_t dstRect = layer->displayFrame;
625
626 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect);
627 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect);
628 hwc_rect_t res = getUnion(l_res, r_res);
629
630 if(!isValidRect(l_res) && !isValidRect(r_res)) {
631 mCurrentFrame.drop[i] = true;
632 mCurrentFrame.dropCount++;
633 } else {
634 /* Reset frame ROI when any layer which needs scaling also needs ROI
635 * cropping */
636 if(!isSameRect(res, dstRect) && needsScaling (layer)) {
637 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
638 mCurrentFrame.dropCount = 0;
639 return false;
640 }
641
radhakrishna4efbdd62014-11-03 13:19:27 +0530642 if (layer->blending == HWC_BLENDING_NONE &&
643 layer->planeAlpha == 0xFF) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800644 visibleRectL = deductRect(visibleRectL, l_res);
645 visibleRectR = deductRect(visibleRectR, r_res);
646 }
647 }
648 }
649 return true;
650}
651/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
652 * are updating. If DirtyRegion is applicable, calculate it by accounting all
653 * the changing layer's dirtyRegion. */
654void MDPCompSplit::generateROI(hwc_context_t *ctx,
655 hwc_display_contents_1_t* list) {
656 if(!canPartialUpdate(ctx, list))
657 return;
658
659 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
660 int lSplit = getLeftSplit(ctx, mDpy);
661
662 int hw_h = (int)ctx->dpyAttr[mDpy].yres;
663 int hw_w = (int)ctx->dpyAttr[mDpy].xres;
664
665 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
666 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
667
668 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
669 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
670
671 for(int index = 0; index < numAppLayers; index++ ) {
672 hwc_layer_1_t* layer = &list->hwLayers[index];
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800673 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800674 if ((mCachedFrame.hnd[index] != layer->handle) ||
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800675 isYuvBuffer(hnd)) {
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700676 hwc_rect_t dst = layer->displayFrame;
677 hwc_rect_t updatingRect = dst;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800678
679#ifdef QCOM_BSP
680 if(!needsScaling(layer) && !layer->transform)
Jeykumar Sankaran71e597c2014-05-07 16:23:14 -0700681 {
682 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
683 int x_off = dst.left - src.left;
684 int y_off = dst.top - src.top;
685 updatingRect = moveRect(layer->dirtyRect, x_off, y_off);
686 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800687#endif
688
689 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect);
690 if(isValidRect(l_dst))
691 l_roi = getUnion(l_roi, l_dst);
692
693 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect);
694 if(isValidRect(r_dst))
695 r_roi = getUnion(r_roi, r_dst);
696 }
697 }
698
Jeykumar Sankarana40a9342014-04-25 09:37:10 -0700699 /* For panels that cannot accept commands in both the interfaces, we cannot
700 * send two ROI's (for each half). We merge them into single ROI and split
701 * them across lSplit for MDP mixer use. The ROI's will be merged again
702 * finally before udpating the panel in the driver. */
703 if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
704 hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
705 l_roi = getIntersection(temp_roi, l_frame);
706 r_roi = getIntersection(temp_roi, r_frame);
707 }
708
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -0800709 /* No layer is updating. Still SF wants a refresh. */
710 if(!isValidRect(l_roi) && !isValidRect(r_roi))
711 return;
712
713 l_roi = getSanitizeROI(l_roi, l_frame);
714 r_roi = getSanitizeROI(r_roi, r_frame);
715
716 ctx->listStats[mDpy].lRoi = l_roi;
717 ctx->listStats[mDpy].rRoi = r_roi;
718
719 if(!validateAndApplyROI(ctx, list))
720 resetROI(ctx, mDpy);
721
722 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
723 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
724 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
725 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
726 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
727 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700728}
729
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800730/* Checks for conditions where all the layers marked for MDP comp cannot be
731 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800732bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800733 hwc_display_contents_1_t* list){
734
Saurabh Shahaa236822013-04-24 18:07:26 -0700735 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800736 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800737
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -0700738 // Fall back to video only composition, if AIV video mode is enabled
739 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -0700740 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
741 __FUNCTION__, mDpy);
742 return false;
743 }
744
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400745 // No Idle fall back, if secure display or secure RGB layers are present or
746 // if there's only a single layer being composed
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -0700747 if(sIdleFallBack && (!ctx->listStats[mDpy].secureUI &&
Naseer Ahmed96bb7782014-09-30 14:02:22 -0400748 !ctx->listStats[mDpy].secureRGBCount) &&
749 (ctx->listStats[mDpy].numAppLayers != 1)) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700750 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
751 return false;
752 }
753
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800754 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700755 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
756 __FUNCTION__,
757 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800758 return false;
759 }
760
Ramkumar Radhakrishnanf26fe9e2014-09-09 13:47:54 -0700761 // if secondary is configuring or Padding round, fall back to video only
762 // composition and release all assigned non VIG pipes from primary.
763 if(isSecondaryConfiguring(ctx)) {
764 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
765 __FUNCTION__);
766 return false;
767 } else if(ctx->isPaddingRound) {
768 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
769 __FUNCTION__,mDpy);
770 return false;
771 }
772
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530773 MDPVersion& mdpHw = MDPVersion::getInstance();
774 if(mDpy > HWC_DISPLAY_PRIMARY &&
Naseer Ahmed9eb5e092014-09-25 13:24:44 -0400775 (priDispW > (int) mdpHw.getMaxMixerWidth()) &&
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530776 (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800777 // Disable MDP comp on Secondary when the primary is highres panel and
778 // the secondary is a normal 1080p, because, MDP comp on secondary under
779 // in such usecase, decimation gets used for downscale and there will be
780 // a quality mismatch when there will be a fallback to GPU comp
781 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
782 __FUNCTION__);
783 return false;
784 }
785
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700786 // check for action safe flag and MDP scaling mode which requires scaling.
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800787 if(ctx->dpyAttr[mDpy].mActionSafePresent
Tatenda Chipeperekwacb2a2432014-08-06 17:45:58 -0700788 || ctx->dpyAttr[mDpy].mMDPScalingMode) {
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800789 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
790 return false;
791 }
792
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800793 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800794 hwc_layer_1_t* layer = &list->hwLayers[i];
795 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800796
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -0800797 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700798 if(!canUseRotator(ctx, mDpy)) {
799 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
800 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700801 return false;
802 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800803 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530804
805 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
806 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700807 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +0530808 if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
809 (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
810 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800811 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700812
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700813 if(ctx->mAD->isDoable()) {
814 return false;
815 }
816
Saurabh Shahaa236822013-04-24 18:07:26 -0700817 //If all above hard conditions are met we can do full or partial MDP comp.
818 bool ret = false;
819 if(fullMDPComp(ctx, list)) {
820 ret = true;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700821 } else if(fullMDPCompWithPTOR(ctx, list)) {
822 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700823 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700824 ret = true;
825 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530826
Saurabh Shahaa236822013-04-24 18:07:26 -0700827 return ret;
828}
829
830bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700831
832 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
833 return false;
834
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700835 //Will benefit presentation / secondary-only layer.
836 if((mDpy > HWC_DISPLAY_PRIMARY) &&
837 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
838 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
839 return false;
840 }
841
842 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
843 for(int i = 0; i < numAppLayers; i++) {
844 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran880da832014-04-18 10:22:35 -0700845 if(not mCurrentFrame.drop[i] and
846 not isSupportedForMDPComp(ctx, layer)) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700847 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
848 return false;
849 }
850 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800851
Saurabh Shahaa236822013-04-24 18:07:26 -0700852 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700853 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
854 sizeof(mCurrentFrame.isFBComposed));
855 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
856 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700857
Raj Kamal389d6e32014-08-04 14:43:24 +0530858 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800859 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530860 }
861
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800862 if(!postHeuristicsHandling(ctx, list)) {
863 ALOGD_IF(isDebug(), "post heuristic handling failed");
864 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700865 return false;
866 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -0700867 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
868 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700869 return true;
870}
871
Sushil Chauhandefd3522014-05-13 18:17:12 -0700872/* Full MDP Composition with Peripheral Tiny Overlap Removal.
873 * MDP bandwidth limitations can be avoided, if the overlap region
874 * covered by the smallest layer at a higher z-order, gets composed
875 * by Copybit on a render buffer, which can be queued to MDP.
876 */
877bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
878 hwc_display_contents_1_t* list) {
879
880 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
881 const int stagesForMDP = min(sMaxPipesPerMixer,
882 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
883
884 // Hard checks where we cannot use this mode
Sushil Chauhanbfc2de02014-07-24 11:52:58 -0700885 if (mDpy || !ctx->mCopyBit[mDpy]) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700886 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
887 return false;
888 }
889
890 // Frame level checks
891 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
892 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
893 isSecurePresent(ctx, mDpy)) {
894 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
895 return false;
896 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700897 // MDP comp checks
898 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700899 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700900 if(not isSupportedForMDPComp(ctx, layer)) {
901 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
902 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700903 }
904 }
905
Sushil Chauhandefd3522014-05-13 18:17:12 -0700906 /* We cannot use this composition mode, if:
907 1. A below layer needs scaling.
908 2. Overlap is not peripheral to display.
909 3. Overlap or a below layer has 90 degree transform.
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700910 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
Sushil Chauhandefd3522014-05-13 18:17:12 -0700911 */
912
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700913 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
914 hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
915 memset(overlapRect, 0, sizeof(overlapRect));
916 int layerPixelCount, minPixelCount = 0;
917 int numPTORLayersFound = 0;
918 for (int i = numAppLayers-1; (i >= 0 &&
919 numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700920 hwc_layer_1_t* layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700921 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhandefd3522014-05-13 18:17:12 -0700922 hwc_rect_t dispFrame = layer->displayFrame;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700923 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
924 // PTOR layer should be peripheral and cannot have transform
925 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
926 has90Transform(layer)) {
927 continue;
928 }
929 if((3 * (layerPixelCount + minPixelCount)) >
930 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
931 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
932 continue;
933 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700934 bool found = false;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700935 for (int j = i-1; j >= 0; j--) {
936 // Check if the layers below this layer qualifies for PTOR comp
937 hwc_layer_1_t* layer = &list->hwLayers[j];
938 hwc_rect_t disFrame = layer->displayFrame;
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700939 // Layer below PTOR is intersecting and has 90 degree transform or
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700940 // needs scaling cannot be supported.
Sushil Chauhan875a92e2014-07-25 12:20:23 -0700941 if (isValidRect(getIntersection(dispFrame, disFrame))) {
942 if (has90Transform(layer) || needsScaling(layer)) {
943 found = false;
944 break;
945 }
946 found = true;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700947 }
948 }
949 // Store the minLayer Index
950 if(found) {
951 minLayerIndex[numPTORLayersFound] = i;
952 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
953 minPixelCount += layerPixelCount;
954 numPTORLayersFound++;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700955 }
956 }
957
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700958 // No overlap layers
959 if (!numPTORLayersFound)
960 return false;
Sushil Chauhandefd3522014-05-13 18:17:12 -0700961
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700962 // Store the displayFrame and the sourceCrops of the layers
963 hwc_rect_t displayFrame[numAppLayers];
964 hwc_rect_t sourceCrop[numAppLayers];
965 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -0700966 hwc_layer_1_t* layer = &list->hwLayers[i];
967 displayFrame[i] = layer->displayFrame;
968 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -0700969 }
Sushil Chauhandefd3522014-05-13 18:17:12 -0700970
Prabhanjan Kandula9889a202014-09-04 21:50:35 +0530971 /**
972 * It's possible that 2 PTOR layers might have overlapping.
973 * In such case, remove the intersection(again if peripheral)
974 * from the lower PTOR layer to avoid overlapping.
975 * If intersection is not on peripheral then compromise
976 * by reducing number of PTOR layers.
977 **/
978 hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
979 if(isValidRect(commonRect)) {
980 overlapRect[1] = deductRect(overlapRect[1], commonRect);
981 list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
982 }
983
984 ctx->mPtorInfo.count = numPTORLayersFound;
985 for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
986 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
987 }
988
989 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
990 // reset PTOR
991 ctx->mPtorInfo.count = 0;
992 if(isValidRect(commonRect)) {
993 // If PTORs are intersecting restore displayframe of PTOR[1]
994 // before returning, as we have modified it above.
995 list->hwLayers[minLayerIndex[1]].displayFrame =
996 displayFrame[minLayerIndex[1]];
997 }
998 return false;
999 }
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001000 private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1001 Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1002
Xu Yangcda012c2014-07-30 21:57:21 +08001003 // Store the blending mode, planeAlpha, and transform of PTOR layers
1004 int32_t blending[numPTORLayersFound];
1005 uint8_t planeAlpha[numPTORLayersFound];
1006 uint32_t transform[numPTORLayersFound];
1007
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001008 for(int j = 0; j < numPTORLayersFound; j++) {
1009 int index = ctx->mPtorInfo.layerIndex[j];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001010
1011 // Update src crop of PTOR layer
1012 hwc_layer_1_t* layer = &list->hwLayers[index];
1013 layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1014 layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1015 layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1016 layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1017
1018 // Store & update w, h, format of PTOR layer
1019 private_handle_t *hnd = (private_handle_t *)layer->handle;
1020 Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1021 layerWhf[j] = whf;
1022 hnd->width = renderBuf->width;
1023 hnd->height = renderBuf->height;
1024 hnd->format = renderBuf->format;
1025
Xu Yangcda012c2014-07-30 21:57:21 +08001026 // Store & update blending mode, planeAlpha and transform of PTOR layer
1027 blending[j] = layer->blending;
1028 planeAlpha[j] = layer->planeAlpha;
1029 transform[j] = layer->transform;
1030 layer->blending = HWC_BLENDING_NONE;
1031 layer->planeAlpha = 0xFF;
1032 layer->transform = 0;
1033
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001034 // Remove overlap from crop & displayFrame of below layers
1035 for (int i = 0; i < index && index !=-1; i++) {
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001036 layer = &list->hwLayers[i];
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001037 if(!isValidRect(getIntersection(layer->displayFrame,
1038 overlapRect[j]))) {
1039 continue;
1040 }
1041 // Update layer attributes
1042 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1043 hwc_rect_t destRect = deductRect(layer->displayFrame,
1044 overlapRect[j]);
1045 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1046 layer->transform);
1047 layer->sourceCropf.left = (float)srcCrop.left;
1048 layer->sourceCropf.top = (float)srcCrop.top;
1049 layer->sourceCropf.right = (float)srcCrop.right;
1050 layer->sourceCropf.bottom = (float)srcCrop.bottom;
1051 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001052 }
1053
1054 mCurrentFrame.mdpCount = numAppLayers;
1055 mCurrentFrame.fbCount = 0;
1056 mCurrentFrame.fbZ = -1;
1057
1058 for (int j = 0; j < numAppLayers; j++)
1059 mCurrentFrame.isFBComposed[j] = false;
1060
1061 bool result = postHeuristicsHandling(ctx, list);
1062
1063 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001064 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001065 hwc_layer_1_t* layer = &list->hwLayers[i];
1066 layer->displayFrame = displayFrame[i];
1067 layer->sourceCropf.left = (float)sourceCrop[i].left;
1068 layer->sourceCropf.top = (float)sourceCrop[i].top;
1069 layer->sourceCropf.right = (float)sourceCrop[i].right;
1070 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1071 }
1072
Xu Yangcda012c2014-07-30 21:57:21 +08001073 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001074 for (int i = 0; i < numPTORLayersFound; i++) {
1075 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001076 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001077 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1078 hnd->width = layerWhf[i].w;
1079 hnd->height = layerWhf[i].h;
1080 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001081 layer->blending = blending[i];
1082 layer->planeAlpha = planeAlpha[i];
1083 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001084 }
1085
Sushil Chauhandefd3522014-05-13 18:17:12 -07001086 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001087 // reset PTOR
1088 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001089 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001090 } else {
1091 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1092 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001093 }
1094
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001095 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1096 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001097 return result;
1098}
1099
Saurabh Shahaa236822013-04-24 18:07:26 -07001100bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1101{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001102 if(!sEnableMixedMode) {
1103 //Mixed mode is disabled. No need to even try caching.
1104 return false;
1105 }
1106
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001107 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001108 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001109 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001110 cacheBasedComp(ctx, list);
1111 } else {
1112 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001113 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001114 }
1115
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001116 return ret;
1117}
1118
1119bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1120 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001121 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1122 return false;
1123
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001124 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001125 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001126 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001127
1128 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1129 for(int i = 0; i < numAppLayers; i++) {
1130 if(!mCurrentFrame.isFBComposed[i]) {
1131 hwc_layer_1_t* layer = &list->hwLayers[i];
1132 if(not isSupportedForMDPComp(ctx, layer)) {
1133 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1134 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001135 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001136 return false;
1137 }
1138 }
1139 }
1140
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001141 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001142 /* mark secure RGB layers for MDP comp */
1143 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301144 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001145 if(!ret) {
1146 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001147 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001148 return false;
1149 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001150
1151 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001152
Raj Kamal389d6e32014-08-04 14:43:24 +05301153 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001154 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301155 }
1156
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001157 //Will benefit cases where a video has non-updating background.
1158 if((mDpy > HWC_DISPLAY_PRIMARY) and
1159 (mdpCount > MAX_SEC_LAYERS)) {
1160 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001161 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001162 return false;
1163 }
1164
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001165 if(!postHeuristicsHandling(ctx, list)) {
1166 ALOGD_IF(isDebug(), "post heuristic handling failed");
1167 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001168 return false;
1169 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001170 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1171 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001172
Saurabh Shahaa236822013-04-24 18:07:26 -07001173 return true;
1174}
1175
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001176bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001177 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001178 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1179 return false;
1180
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001181 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001182 return false;
1183 }
1184
Saurabh Shahb772ae32013-11-18 15:40:02 -08001185 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001186 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1187 const int stagesForMDP = min(sMaxPipesPerMixer,
1188 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001189
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001190 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1191 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1192 int lastMDPSupportedIndex = numAppLayers;
1193 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001194
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001195 //Find the minimum MDP batch size
1196 for(int i = 0; i < numAppLayers;i++) {
1197 if(mCurrentFrame.drop[i]) {
1198 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001199 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001200 }
1201 hwc_layer_1_t* layer = &list->hwLayers[i];
1202 if(not isSupportedForMDPComp(ctx, layer)) {
1203 lastMDPSupportedIndex = i;
1204 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1205 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001206 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001207 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001208 }
1209
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001210 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1211 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1212 mCurrentFrame.dropCount);
1213
1214 //Start at a point where the fb batch should at least have 2 layers, for
1215 //this mode to be justified.
1216 while(fbBatchSize < 2) {
1217 ++fbBatchSize;
1218 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001219 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001220
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001221 //If there are no layers for MDP, this mode doesnt make sense.
1222 if(mdpBatchSize < 1) {
1223 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1224 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001225 return false;
1226 }
1227
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001228 mCurrentFrame.reset(numAppLayers);
1229
1230 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1231 while(mdpBatchSize > 0) {
1232 //Mark layers for MDP comp
1233 int mdpBatchLeft = mdpBatchSize;
1234 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1235 if(mCurrentFrame.drop[i]) {
1236 continue;
1237 }
1238 mCurrentFrame.isFBComposed[i] = false;
1239 --mdpBatchLeft;
1240 }
1241
1242 mCurrentFrame.fbZ = mdpBatchSize;
1243 mCurrentFrame.fbCount = fbBatchSize;
1244 mCurrentFrame.mdpCount = mdpBatchSize;
1245
1246 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1247 __FUNCTION__, mdpBatchSize, fbBatchSize,
1248 mCurrentFrame.dropCount);
1249
1250 if(postHeuristicsHandling(ctx, list)) {
1251 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001252 __FUNCTION__);
1253 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1254 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001255 return true;
1256 }
1257
1258 reset(ctx);
1259 --mdpBatchSize;
1260 ++fbBatchSize;
1261 }
1262
1263 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001264}
1265
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001266bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301267 if(mDpy or isSecurePresent(ctx, mDpy) or
1268 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001269 return false;
1270 }
1271 return true;
1272}
1273
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001274bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1275 hwc_display_contents_1_t* list){
1276 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1277 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1278 mDpy ) {
1279 return false;
1280 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001281 if(ctx->listStats[mDpy].secureUI)
1282 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001283 return true;
1284}
1285
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001286bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1287 hwc_display_contents_1_t* list) {
1288 const bool secureOnly = true;
1289 return videoOnlyComp(ctx, list, not secureOnly) or
1290 videoOnlyComp(ctx, list, secureOnly);
1291}
1292
1293bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001294 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001295 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1296 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001297 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001298
Saurabh Shahaa236822013-04-24 18:07:26 -07001299 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001300 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001301 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001302 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001303
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001304 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1305 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001306 return false;
1307 }
1308
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001309 /* Bail out if we are processing only secured video layers
1310 * and we dont have any */
1311 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001312 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001313 return false;
1314 }
1315
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001316 if(mCurrentFrame.fbCount)
1317 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001318
Raj Kamal389d6e32014-08-04 14:43:24 +05301319 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001320 adjustForSourceSplit(ctx, list);
1321 }
1322
1323 if(!postHeuristicsHandling(ctx, list)) {
1324 ALOGD_IF(isDebug(), "post heuristic handling failed");
1325 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001326 return false;
1327 }
1328
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001329 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1330 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001331 return true;
1332}
1333
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001334/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1335bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1336 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001337 // Fall back to video only composition, if AIV video mode is enabled
1338 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001339 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1340 __FUNCTION__, mDpy);
1341 return false;
1342 }
1343
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001344 const bool secureOnly = true;
1345 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1346 mdpOnlyLayersComp(ctx, list, secureOnly);
1347
1348}
1349
1350bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1351 hwc_display_contents_1_t* list, bool secureOnly) {
1352
1353 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1354 return false;
1355
1356 /* Bail out if we are processing only secured video layers
1357 * and we dont have any */
1358 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1359 reset(ctx);
1360 return false;
1361 }
1362
1363 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1364 mCurrentFrame.reset(numAppLayers);
1365 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1366
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001367 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001368 /* mark secure RGB layers for MDP comp */
1369 updateSecureRGB(ctx, list);
1370
1371 if(mCurrentFrame.mdpCount == 0) {
1372 reset(ctx);
1373 return false;
1374 }
1375
1376 /* find the maximum batch of layers to be marked for framebuffer */
1377 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1378 if(!ret) {
1379 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1380 reset(ctx);
1381 return false;
1382 }
1383
1384 if(sEnableYUVsplit){
1385 adjustForSourceSplit(ctx, list);
1386 }
1387
1388 if(!postHeuristicsHandling(ctx, list)) {
1389 ALOGD_IF(isDebug(), "post heuristic handling failed");
1390 reset(ctx);
1391 return false;
1392 }
1393
1394 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1395 __FUNCTION__);
1396 return true;
1397}
1398
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001399/* Checks for conditions where YUV layers cannot be bypassed */
1400bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001401 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001402 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001403 return false;
1404 }
1405
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001406 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001407 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1408 return false;
1409 }
1410
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001411 if(isSecuring(ctx, layer)) {
1412 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1413 return false;
1414 }
1415
Saurabh Shah4fdde762013-04-30 18:47:33 -07001416 if(!isValidDimension(ctx, layer)) {
1417 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1418 __FUNCTION__);
1419 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001420 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001421
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001422 if(layer->planeAlpha < 0xFF) {
1423 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1424 in video only mode",
1425 __FUNCTION__);
1426 return false;
1427 }
1428
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001429 return true;
1430}
1431
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001432/* Checks for conditions where Secure RGB layers cannot be bypassed */
1433bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1434 if(isSkipLayer(layer)) {
1435 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1436 __FUNCTION__, mDpy);
1437 return false;
1438 }
1439
1440 if(isSecuring(ctx, layer)) {
1441 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1442 return false;
1443 }
1444
1445 if(not isSupportedForMDPComp(ctx, layer)) {
1446 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1447 __FUNCTION__);
1448 return false;
1449 }
1450 return true;
1451}
1452
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301453/* starts at fromIndex and check for each layer to find
1454 * if it it has overlapping with any Updating layer above it in zorder
1455 * till the end of the batch. returns true if it finds any intersection */
1456bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1457 int fromIndex, int toIndex) {
1458 for(int i = fromIndex; i < toIndex; i++) {
1459 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1460 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1461 return false;
1462 }
1463 }
1464 }
1465 return true;
1466}
1467
1468/* Checks if given layer at targetLayerIndex has any
1469 * intersection with all the updating layers in beween
1470 * fromIndex and toIndex. Returns true if it finds intersectiion */
1471bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1472 int fromIndex, int toIndex, int targetLayerIndex) {
1473 for(int i = fromIndex; i <= toIndex; i++) {
1474 if(!mCurrentFrame.isFBComposed[i]) {
1475 if(areLayersIntersecting(&list->hwLayers[i],
1476 &list->hwLayers[targetLayerIndex])) {
1477 return true;
1478 }
1479 }
1480 }
1481 return false;
1482}
1483
1484int MDPComp::getBatch(hwc_display_contents_1_t* list,
1485 int& maxBatchStart, int& maxBatchEnd,
1486 int& maxBatchCount) {
1487 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301488 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001489 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301490 while (i < mCurrentFrame.layerCount) {
1491 int batchCount = 0;
1492 int batchStart = i;
1493 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001494 /* Adjust batch Z order with the dropped layers so far */
1495 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301496 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301497 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301498 while(i < mCurrentFrame.layerCount) {
1499 if(!mCurrentFrame.isFBComposed[i]) {
1500 if(!batchCount) {
1501 i++;
1502 break;
1503 }
1504 updatingLayersAbove++;
1505 i++;
1506 continue;
1507 } else {
1508 if(mCurrentFrame.drop[i]) {
1509 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001510 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301511 continue;
1512 } else if(updatingLayersAbove <= 0) {
1513 batchCount++;
1514 batchEnd = i;
1515 i++;
1516 continue;
1517 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1518
1519 // We have a valid updating layer already. If layer-i not
1520 // have overlapping with all updating layers in between
1521 // batch-start and i, then we can add layer i to batch.
1522 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1523 batchCount++;
1524 batchEnd = i;
1525 i++;
1526 continue;
1527 } else if(canPushBatchToTop(list, batchStart, i)) {
1528 //If All the non-updating layers with in this batch
1529 //does not have intersection with the updating layers
1530 //above in z-order, then we can safely move the batch to
1531 //higher z-order. Increment fbZ as it is moving up.
1532 if( firstZReverseIndex < 0) {
1533 firstZReverseIndex = i;
1534 }
1535 batchCount++;
1536 batchEnd = i;
1537 fbZ += updatingLayersAbove;
1538 i++;
1539 updatingLayersAbove = 0;
1540 continue;
1541 } else {
1542 //both failed.start the loop again from here.
1543 if(firstZReverseIndex >= 0) {
1544 i = firstZReverseIndex;
1545 }
1546 break;
1547 }
1548 }
1549 }
1550 }
1551 if(batchCount > maxBatchCount) {
1552 maxBatchCount = batchCount;
1553 maxBatchStart = batchStart;
1554 maxBatchEnd = batchEnd;
1555 fbZOrder = fbZ;
1556 }
1557 }
1558 return fbZOrder;
1559}
1560
1561bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1562 hwc_display_contents_1_t* list) {
1563 /* Idea is to keep as many non-updating(cached) layers in FB and
1564 * send rest of them through MDP. This is done in 2 steps.
1565 * 1. Find the maximum contiguous batch of non-updating layers.
1566 * 2. See if we can improve this batch size for caching by adding
1567 * opaque layers around the batch, if they don't have
1568 * any overlapping with the updating layers in between.
1569 * NEVER mark an updating layer for caching.
1570 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001571
1572 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001573 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001574 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301575 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001576
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001577 /* Nothing is cached. No batching needed */
1578 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001579 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001580 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001581
1582 /* No MDP comp layers, try to use other comp modes */
1583 if(mCurrentFrame.mdpCount == 0) {
1584 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001585 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001586
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301587 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001588
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301589 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001590 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001591 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001592 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301593 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001594 if(!mCurrentFrame.drop[i]){
1595 //If an unsupported layer is being attempted to
1596 //be pulled out we should fail
1597 if(not isSupportedForMDPComp(ctx, layer)) {
1598 return false;
1599 }
1600 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001601 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001602 }
1603 }
1604
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301605 // update the frame data
1606 mCurrentFrame.fbZ = fbZ;
1607 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001608 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001609 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610
1611 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301612 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001613
1614 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001615}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001616
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001617void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001618 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001619 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001620 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001622 for(int i = 0; i < numAppLayers; i++) {
1623 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001624 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001625 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001626 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001628 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001629 }
1630 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001631
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001632 frame.fbCount = fbCount;
1633 frame.mdpCount = frame.layerCount - frame.fbCount
1634 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001635
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001636 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1637 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001638}
1639
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001640// drop other non-AIV layers from external display list.
1641void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001642 hwc_display_contents_1_t* list) {
1643 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1644 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001645 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001646 mCurrentFrame.dropCount++;
1647 mCurrentFrame.drop[i] = true;
1648 }
1649 }
1650 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1651 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1652 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1653 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1654 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1655 mCurrentFrame.dropCount);
1656}
1657
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001658void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001659 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1661 for(int index = 0;index < nYuvCount; index++){
1662 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1663 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1664
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001665 if(mCurrentFrame.drop[nYuvIndex]) {
1666 continue;
1667 }
1668
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001669 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001670 if(!frame.isFBComposed[nYuvIndex]) {
1671 frame.isFBComposed[nYuvIndex] = true;
1672 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001673 }
1674 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001675 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001676 private_handle_t *hnd = (private_handle_t *)layer->handle;
1677 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001678 frame.isFBComposed[nYuvIndex] = false;
1679 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001680 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681 }
1682 }
1683 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001684
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001685 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1686 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001687}
1688
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001689void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1690 hwc_display_contents_1_t* list) {
1691 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1692 for(int index = 0;index < nSecureRGBCount; index++){
1693 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1694 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1695
1696 if(!isSecureRGBDoable(ctx, layer)) {
1697 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1698 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1699 mCurrentFrame.fbCount++;
1700 }
1701 } else {
1702 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1703 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1704 mCurrentFrame.fbCount--;
1705 }
1706 }
1707 }
1708
1709 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1710 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1711 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1712 mCurrentFrame.fbCount);
1713}
1714
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001715hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1716 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001717 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001718
1719 /* Update only the region of FB needed for composition */
1720 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1721 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1722 hwc_layer_1_t* layer = &list->hwLayers[i];
1723 hwc_rect_t dst = layer->displayFrame;
1724 fbRect = getUnion(fbRect, dst);
1725 }
1726 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001727 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001728 return fbRect;
1729}
1730
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001731bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1732 hwc_display_contents_1_t* list) {
1733
1734 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001735 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001736 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1737 return false;
1738 }
1739
1740 //Limitations checks
1741 if(!hwLimitationsCheck(ctx, list)) {
1742 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1743 return false;
1744 }
1745
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001746 //Configure framebuffer first if applicable
1747 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001748 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001749 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1750 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001751 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1752 __FUNCTION__);
1753 return false;
1754 }
1755 }
1756
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001757 mCurrentFrame.map();
1758
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001759 if(!allocLayerPipes(ctx, list)) {
1760 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001761 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001762 }
1763
1764 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001765 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001766 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001767 int mdpIndex = mCurrentFrame.layerToMDP[index];
1768 hwc_layer_1_t* layer = &list->hwLayers[index];
1769
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301770 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1771 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1772 mdpNextZOrder++;
1773 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001774 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1775 cur_pipe->zOrder = mdpNextZOrder++;
1776
radhakrishnac9a67412013-09-25 17:40:42 +05301777 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301778 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301779 if(configure4k2kYuv(ctx, layer,
1780 mCurrentFrame.mdpToLayer[mdpIndex])
1781 != 0 ){
1782 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1783 for layer %d",__FUNCTION__, index);
1784 return false;
1785 }
1786 else{
1787 mdpNextZOrder++;
1788 }
1789 continue;
1790 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001791 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1792 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301793 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001794 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001795 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001796 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001797 }
1798
Saurabh Shaha36be922013-12-16 18:18:39 -08001799 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1800 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1801 ,__FUNCTION__, mDpy);
1802 return false;
1803 }
1804
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001805 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001806 return true;
1807}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001808
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001809bool MDPComp::resourceCheck(hwc_context_t* ctx,
1810 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001811 const bool fbUsed = mCurrentFrame.fbCount;
1812 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1813 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1814 return false;
1815 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001816 // Init rotCount to number of rotate sessions used by other displays
1817 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1818 // Count the number of rotator sessions required for current display
1819 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1820 if(!mCurrentFrame.isFBComposed[index]) {
1821 hwc_layer_1_t* layer = &list->hwLayers[index];
1822 private_handle_t *hnd = (private_handle_t *)layer->handle;
1823 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1824 rotCount++;
1825 }
1826 }
1827 }
1828 // if number of layers to rotate exceeds max rotator sessions, bail out.
1829 if(rotCount > RotMgr::MAX_ROT_SESS) {
1830 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1831 __FUNCTION__, mDpy);
1832 return false;
1833 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001834 return true;
1835}
1836
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301837bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1838 hwc_display_contents_1_t* list) {
1839
1840 //A-family hw limitation:
1841 //If a layer need alpha scaling, MDP can not support.
1842 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1843 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1844 if(!mCurrentFrame.isFBComposed[i] &&
1845 isAlphaScaled( &list->hwLayers[i])) {
1846 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1847 return false;
1848 }
1849 }
1850 }
1851
1852 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1853 //If multiple layers requires downscaling and also they are overlapping
1854 //fall back to GPU since MDSS can not handle it.
1855 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1856 qdutils::MDPVersion::getInstance().is8x26()) {
1857 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1858 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1859 if(!mCurrentFrame.isFBComposed[i] &&
1860 isDownscaleRequired(botLayer)) {
1861 //if layer-i is marked for MDP and needs downscaling
1862 //check if any MDP layer on top of i & overlaps with layer-i
1863 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1864 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1865 if(!mCurrentFrame.isFBComposed[j] &&
1866 isDownscaleRequired(topLayer)) {
1867 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1868 topLayer->displayFrame);
1869 if(isValidRect(r))
1870 return false;
1871 }
1872 }
1873 }
1874 }
1875 }
1876 return true;
1877}
1878
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001879int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001880 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001881 char property[PROPERTY_VALUE_MAX];
1882
Raj Kamal4393eaa2014-06-06 13:45:20 +05301883 if(!ctx || !list) {
1884 ALOGE("%s: Invalid context or list",__FUNCTION__);
1885 mCachedFrame.reset();
1886 return -1;
1887 }
1888
1889 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001890 if(mDpy == HWC_DISPLAY_PRIMARY) {
1891 sSimulationFlags = 0;
1892 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1893 int currentFlags = atoi(property);
1894 if(currentFlags != sSimulationFlags) {
1895 sSimulationFlags = currentFlags;
1896 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1897 sSimulationFlags, sSimulationFlags);
1898 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001899 }
1900 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001901 // reset PTOR
1902 if(!mDpy)
1903 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001904
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301905 //Do not cache the information for next draw cycle.
1906 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1907 ALOGI("%s: Unsupported layer count for mdp composition",
1908 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001909 mCachedFrame.reset();
1910 return -1;
1911 }
1912
Saurabh Shahb39f8152013-08-22 10:21:44 -07001913 //reset old data
1914 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001915 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1916 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301917
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001918 // Detect the start of animation and fall back to GPU only once to cache
1919 // all the layers in FB and display FB content untill animation completes.
1920 if(ctx->listStats[mDpy].isDisplayAnimating) {
1921 mCurrentFrame.needsRedraw = false;
1922 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1923 mCurrentFrame.needsRedraw = true;
1924 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1925 }
1926 setMDPCompLayerFlags(ctx, list);
1927 mCachedFrame.updateCounts(mCurrentFrame);
1928 ret = -1;
1929 return ret;
1930 } else {
1931 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1932 }
1933
Saurabh Shahb39f8152013-08-22 10:21:44 -07001934 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001935 if(isFrameDoable(ctx)) {
1936 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001937 // if AIV Video mode is enabled, drop all non AIV layers from the
1938 // external display list.
1939 if(ctx->listStats[mDpy].mAIVVideoMode) {
1940 dropNonAIVLayers(ctx, list);
1941 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001942
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001943 // if tryFullFrame fails, try to push all video and secure RGB layers
1944 // to MDP for composition.
1945 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001946 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301947 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001948 setMDPCompLayerFlags(ctx, list);
1949 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001950 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001951 reset(ctx);
1952 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1953 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001954 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001955 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1956 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001957 }
1958 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301959 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1960 enablePartialUpdateForMDP3) {
1961 generateROI(ctx, list);
1962 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1963 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1964 }
1965 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001966 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1967 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001968 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001969 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001970
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001971 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001972 ALOGD("GEOMETRY change: %d",
1973 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001974 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001975 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001976 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001977 }
1978
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001979#ifdef DYNAMIC_FPS
1980 //For primary display, set the dynamic refreshrate
1981 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1982 FrameInfo frame;
1983 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301984 memset(&frame.drop, 0, sizeof(frame.drop));
1985 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001986 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1987 __FUNCTION__);
1988 updateLayerCache(ctx, list, frame);
1989 updateYUV(ctx, list, false /*secure only*/, frame);
1990 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1991 //Set the new fresh rate, if there is only one updating YUV layer
1992 //or there is one single RGB layer with this request
1993 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1994 (frame.layerCount == 1)) {
1995 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1996 }
1997 setRefreshRate(ctx, mDpy, refreshRate);
1998 }
1999#endif
2000
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002001 mCachedFrame.cacheAll(list);
2002 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002003 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002004}
2005
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002006bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302007
2008 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302009 int mdpIndex = mCurrentFrame.layerToMDP[index];
2010 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2011 info.pipeInfo = new MdpYUVPipeInfo;
2012 info.rot = NULL;
2013 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302014
2015 pipe_info.lIndex = ovutils::OV_INVALID;
2016 pipe_info.rIndex = ovutils::OV_INVALID;
2017
Saurabh Shahc62f3982014-03-05 14:28:26 -08002018 Overlay::PipeSpecs pipeSpecs;
2019 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2020 pipeSpecs.needsScaling = true;
2021 pipeSpecs.dpy = mDpy;
2022 pipeSpecs.fb = false;
2023
2024 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302025 if(pipe_info.lIndex == ovutils::OV_INVALID){
2026 bRet = false;
2027 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2028 __FUNCTION__);
2029 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002030 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302031 if(pipe_info.rIndex == ovutils::OV_INVALID){
2032 bRet = false;
2033 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2034 __FUNCTION__);
2035 }
2036 return bRet;
2037}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002038
2039int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2040 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002041 if (ctx->mPtorInfo.isActive()) {
2042 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002043 if (fd < 0) {
2044 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002045 }
2046 }
2047 return fd;
2048}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002049//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002050
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002051void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302052 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002053 //If 4k2k Yuv layer split is possible, and if
2054 //fbz is above 4k2k layer, increment fb zorder by 1
2055 //as we split 4k2k layer and increment zorder for right half
2056 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002057 if(!ctx)
2058 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002059 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302060 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2061 index++) {
2062 if(!mCurrentFrame.isFBComposed[index]) {
2063 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2064 mdpNextZOrder++;
2065 }
2066 mdpNextZOrder++;
2067 hwc_layer_1_t* layer = &list->hwLayers[index];
2068 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302069 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302070 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2071 mCurrentFrame.fbZ += 1;
2072 mdpNextZOrder++;
2073 //As we split 4kx2k yuv layer and program to 2 VG pipes
2074 //(if available) increase mdpcount by 1.
2075 mCurrentFrame.mdpCount++;
2076 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002077 }
2078 }
2079 }
radhakrishnac9a67412013-09-25 17:40:42 +05302080}
2081
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002082/*
2083 * Configures pipe(s) for MDP composition
2084 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002085int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002086 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002087 MdpPipeInfoNonSplit& mdp_info =
2088 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302089 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002090 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002091 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002092
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002093 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2094 __FUNCTION__, layer, zOrder, dest);
2095
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002096 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002097 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002098}
2099
Saurabh Shah88e4d272013-09-03 13:31:29 -07002100bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002101 hwc_display_contents_1_t* list) {
2102 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002103
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002104 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002105
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002106 hwc_layer_1_t* layer = &list->hwLayers[index];
2107 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302108 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002109 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302110 continue;
2111 }
2112 }
2113
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002114 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002115 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002116 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002117 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002118 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002119
Saurabh Shahc62f3982014-03-05 14:28:26 -08002120 Overlay::PipeSpecs pipeSpecs;
2121 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2122 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2123 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2124 (qdutils::MDPVersion::getInstance().is8x26() and
2125 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2126 pipeSpecs.dpy = mDpy;
2127 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002128 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002129
Saurabh Shahc62f3982014-03-05 14:28:26 -08002130 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2131
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002132 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002133 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002134 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002135 }
2136 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002137 return true;
2138}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002139
radhakrishnac9a67412013-09-25 17:40:42 +05302140int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2141 PipeLayerPair& PipeLayerPair) {
2142 MdpYUVPipeInfo& mdp_info =
2143 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2144 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302145 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302146 eDest lDest = mdp_info.lIndex;
2147 eDest rDest = mdp_info.rIndex;
2148
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002149 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302150 lDest, rDest, &PipeLayerPair.rot);
2151}
2152
Saurabh Shah88e4d272013-09-03 13:31:29 -07002153bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002154
Raj Kamal4393eaa2014-06-06 13:45:20 +05302155 if(!isEnabled() or !mModeOn) {
2156 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302157 return true;
2158 }
2159
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002160 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002161 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002162 sHandleTimeout = true;
2163 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002164
2165 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002166 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002167
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002168 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2169 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002170 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002171 if(mCurrentFrame.isFBComposed[i]) continue;
2172
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002173 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002174 private_handle_t *hnd = (private_handle_t *)layer->handle;
2175 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002176 if (!(layer->flags & HWC_COLOR_FILL)) {
2177 ALOGE("%s handle null", __FUNCTION__);
2178 return false;
2179 }
2180 // No PLAY for Color layer
2181 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2182 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002183 }
2184
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002185 int mdpIndex = mCurrentFrame.layerToMDP[i];
2186
Raj Kamal389d6e32014-08-04 14:43:24 +05302187 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302188 {
2189 MdpYUVPipeInfo& pipe_info =
2190 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2191 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2192 ovutils::eDest indexL = pipe_info.lIndex;
2193 ovutils::eDest indexR = pipe_info.rIndex;
2194 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302195 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302196 if(rot) {
2197 rot->queueBuffer(fd, offset);
2198 fd = rot->getDstMemId();
2199 offset = rot->getDstOffset();
2200 }
2201 if(indexL != ovutils::OV_INVALID) {
2202 ovutils::eDest destL = (ovutils::eDest)indexL;
2203 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2204 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2205 if (!ov.queueBuffer(fd, offset, destL)) {
2206 ALOGE("%s: queueBuffer failed for display:%d",
2207 __FUNCTION__, mDpy);
2208 return false;
2209 }
2210 }
2211
2212 if(indexR != ovutils::OV_INVALID) {
2213 ovutils::eDest destR = (ovutils::eDest)indexR;
2214 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2215 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2216 if (!ov.queueBuffer(fd, offset, destR)) {
2217 ALOGE("%s: queueBuffer failed for display:%d",
2218 __FUNCTION__, mDpy);
2219 return false;
2220 }
2221 }
2222 }
2223 else{
2224 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002225 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302226 ovutils::eDest dest = pipe_info.index;
2227 if(dest == ovutils::OV_INVALID) {
2228 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002229 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302230 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002231
radhakrishnac9a67412013-09-25 17:40:42 +05302232 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2233 continue;
2234 }
2235
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002236 int fd = hnd->fd;
2237 uint32_t offset = (uint32_t)hnd->offset;
2238 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2239 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002240 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002241 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002242 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002243 }
2244
radhakrishnac9a67412013-09-25 17:40:42 +05302245 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2246 using pipe: %d", __FUNCTION__, layer,
2247 hnd, dest );
2248
radhakrishnac9a67412013-09-25 17:40:42 +05302249 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2250 if(rot) {
2251 if(!rot->queueBuffer(fd, offset))
2252 return false;
2253 fd = rot->getDstMemId();
2254 offset = rot->getDstOffset();
2255 }
2256
2257 if (!ov.queueBuffer(fd, offset, dest)) {
2258 ALOGE("%s: queueBuffer failed for display:%d ",
2259 __FUNCTION__, mDpy);
2260 return false;
2261 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002262 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002263
2264 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002265 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002266 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002267}
2268
Saurabh Shah88e4d272013-09-03 13:31:29 -07002269//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002270
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002271void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302272 hwc_display_contents_1_t* list){
2273 //if 4kx2k yuv layer is totally present in either in left half
2274 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302275 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302276 if(mCurrentFrame.fbZ >= 0) {
2277 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2278 index++) {
2279 if(!mCurrentFrame.isFBComposed[index]) {
2280 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2281 mdpNextZOrder++;
2282 }
2283 mdpNextZOrder++;
2284 hwc_layer_1_t* layer = &list->hwLayers[index];
2285 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302286 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302287 hwc_rect_t dst = layer->displayFrame;
2288 if((dst.left > lSplit) || (dst.right < lSplit)) {
2289 mCurrentFrame.mdpCount += 1;
2290 }
2291 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2292 mCurrentFrame.fbZ += 1;
2293 mdpNextZOrder++;
2294 }
2295 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002296 }
radhakrishnac9a67412013-09-25 17:40:42 +05302297 }
2298}
2299
Saurabh Shah88e4d272013-09-03 13:31:29 -07002300bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002301 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002302
Saurabh Shahc62f3982014-03-05 14:28:26 -08002303 const int lSplit = getLeftSplit(ctx, mDpy);
2304 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002305 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002306 pipe_info.lIndex = ovutils::OV_INVALID;
2307 pipe_info.rIndex = ovutils::OV_INVALID;
2308
Saurabh Shahc62f3982014-03-05 14:28:26 -08002309 Overlay::PipeSpecs pipeSpecs;
2310 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2311 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2312 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2313 pipeSpecs.dpy = mDpy;
2314 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2315 pipeSpecs.fb = false;
2316
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002317 // Acquire pipe only for the updating half
2318 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2319 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2320
2321 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002322 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002323 if(pipe_info.lIndex == ovutils::OV_INVALID)
2324 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002325 }
2326
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002327 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002328 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2329 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002330 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002331 return false;
2332 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002333
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002334 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002335}
2336
Saurabh Shah88e4d272013-09-03 13:31:29 -07002337bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002338 hwc_display_contents_1_t* list) {
2339 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002340
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002341 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002342
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002343 hwc_layer_1_t* layer = &list->hwLayers[index];
2344 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302345 hwc_rect_t dst = layer->displayFrame;
2346 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302347 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302348 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002349 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302350 continue;
2351 }
2352 }
2353 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002354 int mdpIndex = mCurrentFrame.layerToMDP[index];
2355 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002356 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002357 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002358 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002359
Saurabh Shahc62f3982014-03-05 14:28:26 -08002360 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2361 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2362 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002363 return false;
2364 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002365 }
2366 return true;
2367}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002368
radhakrishnac9a67412013-09-25 17:40:42 +05302369int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2370 PipeLayerPair& PipeLayerPair) {
2371 const int lSplit = getLeftSplit(ctx, mDpy);
2372 hwc_rect_t dst = layer->displayFrame;
2373 if((dst.left > lSplit)||(dst.right < lSplit)){
2374 MdpYUVPipeInfo& mdp_info =
2375 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2376 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302377 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302378 eDest lDest = mdp_info.lIndex;
2379 eDest rDest = mdp_info.rIndex;
2380
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002381 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302382 lDest, rDest, &PipeLayerPair.rot);
2383 }
2384 else{
2385 return configure(ctx, layer, PipeLayerPair);
2386 }
2387}
2388
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002389/*
2390 * Configures pipe(s) for MDP composition
2391 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002392int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002393 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002394 MdpPipeInfoSplit& mdp_info =
2395 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002396 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302397 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002398 eDest lDest = mdp_info.lIndex;
2399 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002400
2401 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2402 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2403
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002404 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002405 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002406}
2407
Saurabh Shah88e4d272013-09-03 13:31:29 -07002408bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002409
Raj Kamal4393eaa2014-06-06 13:45:20 +05302410 if(!isEnabled() or !mModeOn) {
2411 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302412 return true;
2413 }
2414
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002415 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002416 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002417 sHandleTimeout = true;
2418 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002419
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002420 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002421 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002422
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002423 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2424 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002425 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002426 if(mCurrentFrame.isFBComposed[i]) continue;
2427
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002428 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002429 private_handle_t *hnd = (private_handle_t *)layer->handle;
2430 if(!hnd) {
2431 ALOGE("%s handle null", __FUNCTION__);
2432 return false;
2433 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002434
2435 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2436 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002437 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002438
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002439 int mdpIndex = mCurrentFrame.layerToMDP[i];
2440
Raj Kamal389d6e32014-08-04 14:43:24 +05302441 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302442 {
2443 MdpYUVPipeInfo& pipe_info =
2444 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2445 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2446 ovutils::eDest indexL = pipe_info.lIndex;
2447 ovutils::eDest indexR = pipe_info.rIndex;
2448 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302449 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302450 if(rot) {
2451 rot->queueBuffer(fd, offset);
2452 fd = rot->getDstMemId();
2453 offset = rot->getDstOffset();
2454 }
2455 if(indexL != ovutils::OV_INVALID) {
2456 ovutils::eDest destL = (ovutils::eDest)indexL;
2457 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2458 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2459 if (!ov.queueBuffer(fd, offset, destL)) {
2460 ALOGE("%s: queueBuffer failed for display:%d",
2461 __FUNCTION__, mDpy);
2462 return false;
2463 }
2464 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002465
radhakrishnac9a67412013-09-25 17:40:42 +05302466 if(indexR != ovutils::OV_INVALID) {
2467 ovutils::eDest destR = (ovutils::eDest)indexR;
2468 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2469 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2470 if (!ov.queueBuffer(fd, offset, destR)) {
2471 ALOGE("%s: queueBuffer failed for display:%d",
2472 __FUNCTION__, mDpy);
2473 return false;
2474 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002475 }
2476 }
radhakrishnac9a67412013-09-25 17:40:42 +05302477 else{
2478 MdpPipeInfoSplit& pipe_info =
2479 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2480 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002481
radhakrishnac9a67412013-09-25 17:40:42 +05302482 ovutils::eDest indexL = pipe_info.lIndex;
2483 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002484
radhakrishnac9a67412013-09-25 17:40:42 +05302485 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002486 uint32_t offset = (uint32_t)hnd->offset;
2487 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2488 if (!mDpy && (index != -1)) {
2489 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2490 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002491 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002492 }
radhakrishnac9a67412013-09-25 17:40:42 +05302493
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002494 if(ctx->mAD->draw(ctx, fd, offset)) {
2495 fd = ctx->mAD->getDstFd();
2496 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002497 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002498
radhakrishnac9a67412013-09-25 17:40:42 +05302499 if(rot) {
2500 rot->queueBuffer(fd, offset);
2501 fd = rot->getDstMemId();
2502 offset = rot->getDstOffset();
2503 }
2504
2505 //************* play left mixer **********
2506 if(indexL != ovutils::OV_INVALID) {
2507 ovutils::eDest destL = (ovutils::eDest)indexL;
2508 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2509 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2510 if (!ov.queueBuffer(fd, offset, destL)) {
2511 ALOGE("%s: queueBuffer failed for left mixer",
2512 __FUNCTION__);
2513 return false;
2514 }
2515 }
2516
2517 //************* play right mixer **********
2518 if(indexR != ovutils::OV_INVALID) {
2519 ovutils::eDest destR = (ovutils::eDest)indexR;
2520 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2521 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2522 if (!ov.queueBuffer(fd, offset, destR)) {
2523 ALOGE("%s: queueBuffer failed for right mixer",
2524 __FUNCTION__);
2525 return false;
2526 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002527 }
2528 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002529
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002530 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2531 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002532
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002533 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002534}
Saurabh Shahab47c692014-02-12 18:45:57 -08002535
2536//================MDPCompSrcSplit==============================================
2537bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002538 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002539 private_handle_t *hnd = (private_handle_t *)layer->handle;
2540 hwc_rect_t dst = layer->displayFrame;
2541 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2542 pipe_info.lIndex = ovutils::OV_INVALID;
2543 pipe_info.rIndex = ovutils::OV_INVALID;
2544
2545 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2546 //should have a higher priority than the right one. Pipe priorities are
2547 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002548
Saurabh Shahc62f3982014-03-05 14:28:26 -08002549 Overlay::PipeSpecs pipeSpecs;
2550 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2551 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2552 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2553 pipeSpecs.dpy = mDpy;
2554 pipeSpecs.fb = false;
2555
Saurabh Shahab47c692014-02-12 18:45:57 -08002556 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002557 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002558 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002559 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002560 }
2561
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002562 /* Use 2 pipes IF
2563 a) Layer's crop width is > 2048 or
2564 b) Layer's dest width > 2048 or
2565 c) On primary, driver has indicated with caps to split always. This is
2566 based on an empirically derived value of panel height. Applied only
2567 if the layer's width is > mixer's width
2568 */
2569
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302570 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002571 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302572 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002573 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2574 const uint32_t dstWidth = dst.right - dst.left;
2575 const uint32_t dstHeight = dst.bottom - dst.top;
2576 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002577 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002578 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2579 crop.bottom - crop.top;
2580 //Approximation to actual clock, ignoring the common factors in pipe and
2581 //mixer cases like line_time
2582 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2583 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002584
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002585 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2586 //pipe line length, we are still using 2 pipes. This is fine just because
2587 //this is source split where destination doesn't matter. Evaluate later to
2588 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002589 if(dstWidth > mdpHw.getMaxMixerWidth() or
2590 cropWidth > mdpHw.getMaxMixerWidth() or
2591 (primarySplitAlways and
2592 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002593 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002594 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002595 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002596 }
2597
2598 // Return values
2599 // 1 Left pipe is higher priority, do nothing.
2600 // 0 Pipes of same priority.
2601 //-1 Right pipe is of higher priority, needs swap.
2602 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2603 pipe_info.rIndex) == -1) {
2604 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002605 }
2606 }
2607
2608 return true;
2609}
2610
Saurabh Shahab47c692014-02-12 18:45:57 -08002611int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2612 PipeLayerPair& PipeLayerPair) {
2613 private_handle_t *hnd = (private_handle_t *)layer->handle;
2614 if(!hnd) {
2615 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2616 return -1;
2617 }
2618 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2619 MdpPipeInfoSplit& mdp_info =
2620 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2621 Rotator **rot = &PipeLayerPair.rot;
2622 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002623 eDest lDest = mdp_info.lIndex;
2624 eDest rDest = mdp_info.rIndex;
2625 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2626 hwc_rect_t dst = layer->displayFrame;
2627 int transform = layer->transform;
2628 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002629 int rotFlags = ROT_FLAGS_NONE;
2630 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2631 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2632
2633 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2634 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2635
2636 // Handle R/B swap
2637 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2638 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2639 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2640 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2641 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2642 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002643 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002644 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2645 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002646 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002647 /* Calculate the external display position based on MDP downscale,
2648 ActionSafe, and extorientation features. */
2649 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002650
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002651 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302652 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002653 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002654
2655 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2656 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002657 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002658 }
2659
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002660 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002661 (*rot) = ctx->mRotMgr->getNext();
2662 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002663 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002664 //If the video is using a single pipe, enable BWC
2665 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002666 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2667 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002668 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002669 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002670 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002671 ALOGE("%s: configRotator failed!", __FUNCTION__);
2672 return -1;
2673 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002674 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002675 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002676 }
2677
2678 //If 2 pipes being used, divide layer into half, crop and dst
2679 hwc_rect_t cropL = crop;
2680 hwc_rect_t cropR = crop;
2681 hwc_rect_t dstL = dst;
2682 hwc_rect_t dstR = dst;
2683 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2684 cropL.right = (crop.right + crop.left) / 2;
2685 cropR.left = cropL.right;
2686 sanitizeSourceCrop(cropL, cropR, hnd);
2687
Saurabh Shahb729b192014-08-15 18:04:24 -07002688 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002689 //Swap crops on H flip since 2 pipes are being used
2690 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2691 hwc_rect_t tmp = cropL;
2692 cropL = cropR;
2693 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002694 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002695 }
2696
Saurabh Shahb729b192014-08-15 18:04:24 -07002697 //cropSwap trick: If the src and dst widths are both odd, let us say
2698 //2507, then splitting both into half would cause left width to be 1253
2699 //and right 1254. If crop is swapped because of H flip, this will cause
2700 //left crop width to be 1254, whereas left dst width remains 1253, thus
2701 //inducing a scaling that is unaccounted for. To overcome that we add 1
2702 //to the dst width if there is a cropSwap. So if the original width was
2703 //2507, the left dst width will be 1254. Even if the original width was
2704 //even for ex: 2508, the left dst width will still remain 1254.
2705 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002706 dstR.left = dstL.right;
2707 }
2708
2709 //For the mdp, since either we are pre-rotating or MDP does flips
2710 orient = OVERLAY_TRANSFORM_0;
2711 transform = 0;
2712
2713 //configure left pipe
2714 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002715 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002716 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2717 (ovutils::eBlending) getBlending(layer->blending));
2718
2719 if(configMdp(ctx->mOverlay, pargL, orient,
2720 cropL, dstL, metadata, lDest) < 0) {
2721 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2722 return -1;
2723 }
2724 }
2725
2726 //configure right pipe
2727 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002728 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002729 static_cast<eRotFlags>(rotFlags),
2730 layer->planeAlpha,
2731 (ovutils::eBlending) getBlending(layer->blending));
2732 if(configMdp(ctx->mOverlay, pargR, orient,
2733 cropR, dstR, metadata, rDest) < 0) {
2734 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2735 return -1;
2736 }
2737 }
2738
2739 return 0;
2740}
2741
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002742}; //namespace
2743