blob: 466151b691a10bac29d305f322a9226583405bea [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,
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301044 getIntersection(layer->displayFrame, overlapRect[j]));
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001045 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
Dileep Kumar Reddi72058b82014-11-11 16:03:03 +05301058 for (int j = 0; j < numAppLayers; j++) {
1059 if(isValidRect(list->hwLayers[j].displayFrame)) {
1060 mCurrentFrame.isFBComposed[j] = false;
1061 } else {
1062 mCurrentFrame.mdpCount--;
1063 mCurrentFrame.drop[j] = true;
1064 }
1065 }
Sushil Chauhandefd3522014-05-13 18:17:12 -07001066
1067 bool result = postHeuristicsHandling(ctx, list);
1068
1069 // Restore layer attributes
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001070 for(int i = 0; i < numAppLayers; i++) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07001071 hwc_layer_1_t* layer = &list->hwLayers[i];
1072 layer->displayFrame = displayFrame[i];
1073 layer->sourceCropf.left = (float)sourceCrop[i].left;
1074 layer->sourceCropf.top = (float)sourceCrop[i].top;
1075 layer->sourceCropf.right = (float)sourceCrop[i].right;
1076 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1077 }
1078
Xu Yangcda012c2014-07-30 21:57:21 +08001079 // Restore w,h,f, blending attributes, and transform of PTOR layers
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001080 for (int i = 0; i < numPTORLayersFound; i++) {
1081 int idx = ctx->mPtorInfo.layerIndex[i];
Xu Yangcda012c2014-07-30 21:57:21 +08001082 hwc_layer_1_t* layer = &list->hwLayers[idx];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001083 private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1084 hnd->width = layerWhf[i].w;
1085 hnd->height = layerWhf[i].h;
1086 hnd->format = layerWhf[i].format;
Xu Yangcda012c2014-07-30 21:57:21 +08001087 layer->blending = blending[i];
1088 layer->planeAlpha = planeAlpha[i];
1089 layer->transform = transform[i];
Sushil Chauhan875a92e2014-07-25 12:20:23 -07001090 }
1091
Sushil Chauhandefd3522014-05-13 18:17:12 -07001092 if (!result) {
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001093 // reset PTOR
1094 ctx->mPtorInfo.count = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07001095 reset(ctx);
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001096 } else {
1097 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1098 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]);
Sushil Chauhandefd3522014-05-13 18:17:12 -07001099 }
1100
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001101 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1102 (result ? "successful" : "failed"));
Sushil Chauhandefd3522014-05-13 18:17:12 -07001103 return result;
1104}
1105
Saurabh Shahaa236822013-04-24 18:07:26 -07001106bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1107{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -07001108 if(!sEnableMixedMode) {
1109 //Mixed mode is disabled. No need to even try caching.
1110 return false;
1111 }
1112
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001113 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001114 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001115 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001116 cacheBasedComp(ctx, list);
1117 } else {
1118 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001119 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001120 }
1121
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001122 return ret;
1123}
1124
1125bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1126 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001127 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1128 return false;
1129
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001130 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -07001131 mCurrentFrame.reset(numAppLayers);
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001132 updateLayerCache(ctx, list, mCurrentFrame);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001133
1134 //If an MDP marked layer is unsupported cannot do partial MDP Comp
1135 for(int i = 0; i < numAppLayers; i++) {
1136 if(!mCurrentFrame.isFBComposed[i]) {
1137 hwc_layer_1_t* layer = &list->hwLayers[i];
1138 if(not isSupportedForMDPComp(ctx, layer)) {
1139 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1140 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001141 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001142 return false;
1143 }
1144 }
1145 }
1146
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001147 updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001148 /* mark secure RGB layers for MDP comp */
1149 updateSecureRGB(ctx, list);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301150 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001151 if(!ret) {
1152 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001153 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001154 return false;
1155 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001156
1157 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001158
Raj Kamal389d6e32014-08-04 14:43:24 +05301159 if(sEnableYUVsplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001160 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +05301161 }
1162
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001163 //Will benefit cases where a video has non-updating background.
1164 if((mDpy > HWC_DISPLAY_PRIMARY) and
1165 (mdpCount > MAX_SEC_LAYERS)) {
1166 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001167 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001168 return false;
1169 }
1170
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001171 if(!postHeuristicsHandling(ctx, list)) {
1172 ALOGD_IF(isDebug(), "post heuristic handling failed");
1173 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001174 return false;
1175 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001176 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1177 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001178
Saurabh Shahaa236822013-04-24 18:07:26 -07001179 return true;
1180}
1181
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001182bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -08001183 hwc_display_contents_1_t* list) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001184 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1185 return false;
1186
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001187 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001188 return false;
1189 }
1190
Saurabh Shahb772ae32013-11-18 15:40:02 -08001191 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001192 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1193 const int stagesForMDP = min(sMaxPipesPerMixer,
1194 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -08001195
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001196 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1197 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1198 int lastMDPSupportedIndex = numAppLayers;
1199 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001200
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001201 //Find the minimum MDP batch size
1202 for(int i = 0; i < numAppLayers;i++) {
1203 if(mCurrentFrame.drop[i]) {
1204 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001205 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001206 }
1207 hwc_layer_1_t* layer = &list->hwLayers[i];
1208 if(not isSupportedForMDPComp(ctx, layer)) {
1209 lastMDPSupportedIndex = i;
1210 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1211 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001212 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001213 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001214 }
1215
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001216 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1217 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1218 mCurrentFrame.dropCount);
1219
1220 //Start at a point where the fb batch should at least have 2 layers, for
1221 //this mode to be justified.
1222 while(fbBatchSize < 2) {
1223 ++fbBatchSize;
1224 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -08001225 }
Saurabh Shahb772ae32013-11-18 15:40:02 -08001226
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001227 //If there are no layers for MDP, this mode doesnt make sense.
1228 if(mdpBatchSize < 1) {
1229 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1230 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -08001231 return false;
1232 }
1233
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001234 mCurrentFrame.reset(numAppLayers);
1235
1236 //Try with successively smaller mdp batch sizes until we succeed or reach 1
1237 while(mdpBatchSize > 0) {
1238 //Mark layers for MDP comp
1239 int mdpBatchLeft = mdpBatchSize;
1240 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1241 if(mCurrentFrame.drop[i]) {
1242 continue;
1243 }
1244 mCurrentFrame.isFBComposed[i] = false;
1245 --mdpBatchLeft;
1246 }
1247
1248 mCurrentFrame.fbZ = mdpBatchSize;
1249 mCurrentFrame.fbCount = fbBatchSize;
1250 mCurrentFrame.mdpCount = mdpBatchSize;
1251
1252 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1253 __FUNCTION__, mdpBatchSize, fbBatchSize,
1254 mCurrentFrame.dropCount);
1255
1256 if(postHeuristicsHandling(ctx, list)) {
1257 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001258 __FUNCTION__);
1259 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1260 __FUNCTION__);
Saurabh Shahbe7bd322014-02-20 16:18:45 -08001261 return true;
1262 }
1263
1264 reset(ctx);
1265 --mdpBatchSize;
1266 ++fbBatchSize;
1267 }
1268
1269 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -08001270}
1271
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001272bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +05301273 if(mDpy or isSecurePresent(ctx, mDpy) or
1274 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -07001275 return false;
1276 }
1277 return true;
1278}
1279
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001280bool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1281 hwc_display_contents_1_t* list){
1282 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1283 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1284 mDpy ) {
1285 return false;
1286 }
Jeykumar Sankaran4dd10ab2014-07-02 12:23:09 -07001287 if(ctx->listStats[mDpy].secureUI)
1288 return false;
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001289 return true;
1290}
1291
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001292bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1293 hwc_display_contents_1_t* list) {
1294 const bool secureOnly = true;
1295 return videoOnlyComp(ctx, list, not secureOnly) or
1296 videoOnlyComp(ctx, list, secureOnly);
1297}
1298
1299bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001300 hwc_display_contents_1_t* list, bool secureOnly) {
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001301 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1302 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001303 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001304
Saurabh Shahaa236822013-04-24 18:07:26 -07001305 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -07001306 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001307 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Saurabh Shah4fdde762013-04-30 18:47:33 -07001308 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001309
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001310 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1311 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -07001312 return false;
1313 }
1314
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001315 /* Bail out if we are processing only secured video layers
1316 * and we dont have any */
1317 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001318 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -08001319 return false;
1320 }
1321
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001322 if(mCurrentFrame.fbCount)
1323 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -07001324
Raj Kamal389d6e32014-08-04 14:43:24 +05301325 if(sEnableYUVsplit){
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001326 adjustForSourceSplit(ctx, list);
1327 }
1328
1329 if(!postHeuristicsHandling(ctx, list)) {
1330 ALOGD_IF(isDebug(), "post heuristic handling failed");
1331 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001332 return false;
1333 }
1334
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001335 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1336 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001337 return true;
1338}
1339
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001340/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1341bool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1342 hwc_display_contents_1_t* list) {
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001343 // Fall back to video only composition, if AIV video mode is enabled
1344 if(ctx->listStats[mDpy].mAIVVideoMode) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001345 ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1346 __FUNCTION__, mDpy);
1347 return false;
1348 }
1349
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001350 const bool secureOnly = true;
1351 return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1352 mdpOnlyLayersComp(ctx, list, secureOnly);
1353
1354}
1355
1356bool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1357 hwc_display_contents_1_t* list, bool secureOnly) {
1358
1359 if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1360 return false;
1361
1362 /* Bail out if we are processing only secured video layers
1363 * and we dont have any */
1364 if(!isSecurePresent(ctx, mDpy) && secureOnly){
1365 reset(ctx);
1366 return false;
1367 }
1368
1369 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1370 mCurrentFrame.reset(numAppLayers);
1371 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1372
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001373 updateYUV(ctx, list, secureOnly, mCurrentFrame);
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001374 /* mark secure RGB layers for MDP comp */
1375 updateSecureRGB(ctx, list);
1376
1377 if(mCurrentFrame.mdpCount == 0) {
1378 reset(ctx);
1379 return false;
1380 }
1381
1382 /* find the maximum batch of layers to be marked for framebuffer */
1383 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1384 if(!ret) {
1385 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1386 reset(ctx);
1387 return false;
1388 }
1389
1390 if(sEnableYUVsplit){
1391 adjustForSourceSplit(ctx, list);
1392 }
1393
1394 if(!postHeuristicsHandling(ctx, list)) {
1395 ALOGD_IF(isDebug(), "post heuristic handling failed");
1396 reset(ctx);
1397 return false;
1398 }
1399
1400 ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1401 __FUNCTION__);
1402 return true;
1403}
1404
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001405/* Checks for conditions where YUV layers cannot be bypassed */
1406bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001407 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001408 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001409 return false;
1410 }
1411
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001412 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001413 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1414 return false;
1415 }
1416
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001417 if(isSecuring(ctx, layer)) {
1418 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1419 return false;
1420 }
1421
Saurabh Shah4fdde762013-04-30 18:47:33 -07001422 if(!isValidDimension(ctx, layer)) {
1423 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1424 __FUNCTION__);
1425 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001426 }
Saurabh Shah4fdde762013-04-30 18:47:33 -07001427
Naseer Ahmeddc61a972013-07-10 17:50:54 -04001428 if(layer->planeAlpha < 0xFF) {
1429 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1430 in video only mode",
1431 __FUNCTION__);
1432 return false;
1433 }
1434
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001435 return true;
1436}
1437
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001438/* Checks for conditions where Secure RGB layers cannot be bypassed */
1439bool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1440 if(isSkipLayer(layer)) {
1441 ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1442 __FUNCTION__, mDpy);
1443 return false;
1444 }
1445
1446 if(isSecuring(ctx, layer)) {
1447 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1448 return false;
1449 }
1450
1451 if(not isSupportedForMDPComp(ctx, layer)) {
1452 ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1453 __FUNCTION__);
1454 return false;
1455 }
1456 return true;
1457}
1458
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301459/* starts at fromIndex and check for each layer to find
1460 * if it it has overlapping with any Updating layer above it in zorder
1461 * till the end of the batch. returns true if it finds any intersection */
1462bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1463 int fromIndex, int toIndex) {
1464 for(int i = fromIndex; i < toIndex; i++) {
1465 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1466 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1467 return false;
1468 }
1469 }
1470 }
1471 return true;
1472}
1473
1474/* Checks if given layer at targetLayerIndex has any
1475 * intersection with all the updating layers in beween
1476 * fromIndex and toIndex. Returns true if it finds intersectiion */
1477bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1478 int fromIndex, int toIndex, int targetLayerIndex) {
1479 for(int i = fromIndex; i <= toIndex; i++) {
1480 if(!mCurrentFrame.isFBComposed[i]) {
1481 if(areLayersIntersecting(&list->hwLayers[i],
1482 &list->hwLayers[targetLayerIndex])) {
1483 return true;
1484 }
1485 }
1486 }
1487 return false;
1488}
1489
1490int MDPComp::getBatch(hwc_display_contents_1_t* list,
1491 int& maxBatchStart, int& maxBatchEnd,
1492 int& maxBatchCount) {
1493 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301494 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001495 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301496 while (i < mCurrentFrame.layerCount) {
1497 int batchCount = 0;
1498 int batchStart = i;
1499 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001500 /* Adjust batch Z order with the dropped layers so far */
1501 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301502 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +05301503 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301504 while(i < mCurrentFrame.layerCount) {
1505 if(!mCurrentFrame.isFBComposed[i]) {
1506 if(!batchCount) {
1507 i++;
1508 break;
1509 }
1510 updatingLayersAbove++;
1511 i++;
1512 continue;
1513 } else {
1514 if(mCurrentFrame.drop[i]) {
1515 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -08001516 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301517 continue;
1518 } else if(updatingLayersAbove <= 0) {
1519 batchCount++;
1520 batchEnd = i;
1521 i++;
1522 continue;
1523 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1524
1525 // We have a valid updating layer already. If layer-i not
1526 // have overlapping with all updating layers in between
1527 // batch-start and i, then we can add layer i to batch.
1528 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1529 batchCount++;
1530 batchEnd = i;
1531 i++;
1532 continue;
1533 } else if(canPushBatchToTop(list, batchStart, i)) {
1534 //If All the non-updating layers with in this batch
1535 //does not have intersection with the updating layers
1536 //above in z-order, then we can safely move the batch to
1537 //higher z-order. Increment fbZ as it is moving up.
1538 if( firstZReverseIndex < 0) {
1539 firstZReverseIndex = i;
1540 }
1541 batchCount++;
1542 batchEnd = i;
1543 fbZ += updatingLayersAbove;
1544 i++;
1545 updatingLayersAbove = 0;
1546 continue;
1547 } else {
1548 //both failed.start the loop again from here.
1549 if(firstZReverseIndex >= 0) {
1550 i = firstZReverseIndex;
1551 }
1552 break;
1553 }
1554 }
1555 }
1556 }
1557 if(batchCount > maxBatchCount) {
1558 maxBatchCount = batchCount;
1559 maxBatchStart = batchStart;
1560 maxBatchEnd = batchEnd;
1561 fbZOrder = fbZ;
1562 }
1563 }
1564 return fbZOrder;
1565}
1566
1567bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
1568 hwc_display_contents_1_t* list) {
1569 /* Idea is to keep as many non-updating(cached) layers in FB and
1570 * send rest of them through MDP. This is done in 2 steps.
1571 * 1. Find the maximum contiguous batch of non-updating layers.
1572 * 2. See if we can improve this batch size for caching by adding
1573 * opaque layers around the batch, if they don't have
1574 * any overlapping with the updating layers in between.
1575 * NEVER mark an updating layer for caching.
1576 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001577
1578 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001579 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001580 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301581 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001582
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001583 /* Nothing is cached. No batching needed */
1584 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001585 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001586 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001587
1588 /* No MDP comp layers, try to use other comp modes */
1589 if(mCurrentFrame.mdpCount == 0) {
1590 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001591 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001592
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301593 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001594
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301595 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001596 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001597 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001598 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301599 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001600 if(!mCurrentFrame.drop[i]){
1601 //If an unsupported layer is being attempted to
1602 //be pulled out we should fail
1603 if(not isSupportedForMDPComp(ctx, layer)) {
1604 return false;
1605 }
1606 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001607 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001608 }
1609 }
1610
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301611 // update the frame data
1612 mCurrentFrame.fbZ = fbZ;
1613 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001614 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001615 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001616
1617 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301618 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001619
1620 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001621}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001622
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001623void MDPComp::updateLayerCache(hwc_context_t* ctx,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001624 hwc_display_contents_1_t* list, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001625 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001626 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001627
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001628 for(int i = 0; i < numAppLayers; i++) {
1629 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001630 if(!frame.drop[i])
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001631 fbCount++;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001632 frame.isFBComposed[i] = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001633 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001634 frame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001635 }
1636 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001637
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001638 frame.fbCount = fbCount;
1639 frame.mdpCount = frame.layerCount - frame.fbCount
1640 - frame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001641
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001642 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1643 __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001644}
1645
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001646// drop other non-AIV layers from external display list.
1647void MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001648 hwc_display_contents_1_t* list) {
1649 for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1650 hwc_layer_1_t * layer = &list->hwLayers[i];
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001651 if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07001652 mCurrentFrame.dropCount++;
1653 mCurrentFrame.drop[i] = true;
1654 }
1655 }
1656 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1657 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1658 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1659 ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1660 __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1661 mCurrentFrame.dropCount);
1662}
1663
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001664void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001665 bool secureOnly, FrameInfo& frame) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001666 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1667 for(int index = 0;index < nYuvCount; index++){
1668 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1669 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1670
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001671 if(mCurrentFrame.drop[nYuvIndex]) {
1672 continue;
1673 }
1674
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001675 if(!isYUVDoable(ctx, layer)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001676 if(!frame.isFBComposed[nYuvIndex]) {
1677 frame.isFBComposed[nYuvIndex] = true;
1678 frame.fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001679 }
1680 } else {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001681 if(frame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001682 private_handle_t *hnd = (private_handle_t *)layer->handle;
1683 if(!secureOnly || isSecureBuffer(hnd)) {
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001684 frame.isFBComposed[nYuvIndex] = false;
1685 frame.fbCount--;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001686 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001687 }
1688 }
1689 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001690
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001691 frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1692 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001693}
1694
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001695void MDPComp::updateSecureRGB(hwc_context_t* ctx,
1696 hwc_display_contents_1_t* list) {
1697 int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1698 for(int index = 0;index < nSecureRGBCount; index++){
1699 int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1700 hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1701
1702 if(!isSecureRGBDoable(ctx, layer)) {
1703 if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1704 mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1705 mCurrentFrame.fbCount++;
1706 }
1707 } else {
1708 if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1709 mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1710 mCurrentFrame.fbCount--;
1711 }
1712 }
1713 }
1714
1715 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1716 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1717 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1718 mCurrentFrame.fbCount);
1719}
1720
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001721hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1722 hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001723 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001724
1725 /* Update only the region of FB needed for composition */
1726 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1727 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1728 hwc_layer_1_t* layer = &list->hwLayers[i];
1729 hwc_rect_t dst = layer->displayFrame;
1730 fbRect = getUnion(fbRect, dst);
1731 }
1732 }
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001733 trimAgainstROI(ctx, fbRect);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001734 return fbRect;
1735}
1736
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001737bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1738 hwc_display_contents_1_t* list) {
1739
1740 //Capability checks
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001741 if(!resourceCheck(ctx, list)) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001742 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1743 return false;
1744 }
1745
1746 //Limitations checks
1747 if(!hwLimitationsCheck(ctx, list)) {
1748 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1749 return false;
1750 }
1751
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001752 //Configure framebuffer first if applicable
1753 if(mCurrentFrame.fbZ >= 0) {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001754 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001755 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1756 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001757 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1758 __FUNCTION__);
1759 return false;
1760 }
1761 }
1762
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001763 mCurrentFrame.map();
1764
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001765 if(!allocLayerPipes(ctx, list)) {
1766 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001767 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001768 }
1769
1770 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001771 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001772 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001773 int mdpIndex = mCurrentFrame.layerToMDP[index];
1774 hwc_layer_1_t* layer = &list->hwLayers[index];
1775
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301776 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1777 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1778 mdpNextZOrder++;
1779 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001780 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1781 cur_pipe->zOrder = mdpNextZOrder++;
1782
radhakrishnac9a67412013-09-25 17:40:42 +05301783 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05301784 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05301785 if(configure4k2kYuv(ctx, layer,
1786 mCurrentFrame.mdpToLayer[mdpIndex])
1787 != 0 ){
1788 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1789 for layer %d",__FUNCTION__, index);
1790 return false;
1791 }
1792 else{
1793 mdpNextZOrder++;
1794 }
1795 continue;
1796 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001797 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1798 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301799 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001800 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001801 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001802 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001803 }
1804
Saurabh Shaha36be922013-12-16 18:18:39 -08001805 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1806 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1807 ,__FUNCTION__, mDpy);
1808 return false;
1809 }
1810
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001811 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001812 return true;
1813}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001814
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001815bool MDPComp::resourceCheck(hwc_context_t* ctx,
1816 hwc_display_contents_1_t* list) {
Saurabh Shah173f4242013-11-20 09:50:12 -08001817 const bool fbUsed = mCurrentFrame.fbCount;
1818 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1819 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1820 return false;
1821 }
Ramkumar Radhakrishnan9d20b392013-11-15 19:32:47 -08001822 // Init rotCount to number of rotate sessions used by other displays
1823 int rotCount = ctx->mRotMgr->getNumActiveSessions();
1824 // Count the number of rotator sessions required for current display
1825 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1826 if(!mCurrentFrame.isFBComposed[index]) {
1827 hwc_layer_1_t* layer = &list->hwLayers[index];
1828 private_handle_t *hnd = (private_handle_t *)layer->handle;
1829 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1830 rotCount++;
1831 }
1832 }
1833 }
1834 // if number of layers to rotate exceeds max rotator sessions, bail out.
1835 if(rotCount > RotMgr::MAX_ROT_SESS) {
1836 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d",
1837 __FUNCTION__, mDpy);
1838 return false;
1839 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001840 return true;
1841}
1842
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301843bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1844 hwc_display_contents_1_t* list) {
1845
1846 //A-family hw limitation:
1847 //If a layer need alpha scaling, MDP can not support.
1848 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1849 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1850 if(!mCurrentFrame.isFBComposed[i] &&
1851 isAlphaScaled( &list->hwLayers[i])) {
1852 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1853 return false;
1854 }
1855 }
1856 }
1857
1858 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1859 //If multiple layers requires downscaling and also they are overlapping
1860 //fall back to GPU since MDSS can not handle it.
1861 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1862 qdutils::MDPVersion::getInstance().is8x26()) {
1863 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1864 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1865 if(!mCurrentFrame.isFBComposed[i] &&
1866 isDownscaleRequired(botLayer)) {
1867 //if layer-i is marked for MDP and needs downscaling
1868 //check if any MDP layer on top of i & overlaps with layer-i
1869 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1870 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1871 if(!mCurrentFrame.isFBComposed[j] &&
1872 isDownscaleRequired(topLayer)) {
1873 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1874 topLayer->displayFrame);
1875 if(isValidRect(r))
1876 return false;
1877 }
1878 }
1879 }
1880 }
1881 }
1882 return true;
1883}
1884
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001885int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001886 int ret = 0;
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001887 char property[PROPERTY_VALUE_MAX];
1888
Raj Kamal4393eaa2014-06-06 13:45:20 +05301889 if(!ctx || !list) {
1890 ALOGE("%s: Invalid context or list",__FUNCTION__);
1891 mCachedFrame.reset();
1892 return -1;
1893 }
1894
1895 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah286cf122014-09-08 14:13:08 -07001896 if(mDpy == HWC_DISPLAY_PRIMARY) {
1897 sSimulationFlags = 0;
1898 if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1899 int currentFlags = atoi(property);
1900 if(currentFlags != sSimulationFlags) {
1901 sSimulationFlags = currentFlags;
1902 ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
1903 sSimulationFlags, sSimulationFlags);
1904 }
Jeykumar Sankaran0ad97c42014-03-09 23:00:53 -07001905 }
1906 }
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07001907 // reset PTOR
1908 if(!mDpy)
1909 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001910
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301911 //Do not cache the information for next draw cycle.
1912 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1913 ALOGI("%s: Unsupported layer count for mdp composition",
1914 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001915 mCachedFrame.reset();
1916 return -1;
1917 }
1918
Saurabh Shahb39f8152013-08-22 10:21:44 -07001919 //reset old data
1920 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001921 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1922 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301923
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001924 // Detect the start of animation and fall back to GPU only once to cache
1925 // all the layers in FB and display FB content untill animation completes.
1926 if(ctx->listStats[mDpy].isDisplayAnimating) {
1927 mCurrentFrame.needsRedraw = false;
1928 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1929 mCurrentFrame.needsRedraw = true;
1930 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1931 }
1932 setMDPCompLayerFlags(ctx, list);
1933 mCachedFrame.updateCounts(mCurrentFrame);
1934 ret = -1;
1935 return ret;
1936 } else {
1937 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1938 }
1939
Saurabh Shahb39f8152013-08-22 10:21:44 -07001940 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001941 if(isFrameDoable(ctx)) {
1942 generateROI(ctx, list);
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001943 // if AIV Video mode is enabled, drop all non AIV layers from the
1944 // external display list.
1945 if(ctx->listStats[mDpy].mAIVVideoMode) {
1946 dropNonAIVLayers(ctx, list);
1947 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001948
Ramkumar Radhakrishnan4ec775f2014-07-23 17:43:18 -07001949 // if tryFullFrame fails, try to push all video and secure RGB layers
1950 // to MDP for composition.
1951 mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07001952 tryVideoOnly(ctx, list);
Raj Kamal4393eaa2014-06-06 13:45:20 +05301953 if(mModeOn) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001954 setMDPCompLayerFlags(ctx, list);
1955 } else {
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08001956 resetROI(ctx, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001957 reset(ctx);
1958 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1959 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001960 ret = -1;
Saurabh Shah286cf122014-09-08 14:13:08 -07001961 ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
1962 "MDP Composition Strategies Failed");
Saurabh Shahb39f8152013-08-22 10:21:44 -07001963 }
1964 } else {
Dileep Kumar Reddi4070e932014-09-30 09:00:57 +05301965 if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
1966 enablePartialUpdateForMDP3) {
1967 generateROI(ctx, list);
1968 for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
1969 ctx->copybitDrop[i] = mCurrentFrame.drop[i];
1970 }
1971 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001972 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1973 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001974 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001975 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001976
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001977 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001978 ALOGD("GEOMETRY change: %d",
1979 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001980 android::String8 sDump("");
Jeykumar Sankaran6850ac62014-05-27 10:07:26 -07001981 dump(sDump, ctx);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001982 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001983 }
1984
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001985#ifdef DYNAMIC_FPS
1986 //For primary display, set the dynamic refreshrate
1987 if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported()) {
1988 FrameInfo frame;
1989 frame.reset(mCurrentFrame.layerCount);
Raj Kamal18e946e2014-10-10 14:23:47 +05301990 memset(&frame.drop, 0, sizeof(frame.drop));
1991 frame.dropCount = 0;
Arun Kumar K.Ra727a882014-08-20 17:14:26 -07001992 ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo for Dyn Refresh Rate",
1993 __FUNCTION__);
1994 updateLayerCache(ctx, list, frame);
1995 updateYUV(ctx, list, false /*secure only*/, frame);
1996 uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1997 //Set the new fresh rate, if there is only one updating YUV layer
1998 //or there is one single RGB layer with this request
1999 if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
2000 (frame.layerCount == 1)) {
2001 refreshRate = ctx->listStats[mDpy].refreshRateRequest;
2002 }
2003 setRefreshRate(ctx, mDpy, refreshRate);
2004 }
2005#endif
2006
Saurabh Shahdf4741d2013-12-12 16:40:28 -08002007 mCachedFrame.cacheAll(list);
2008 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07002009 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002010}
2011
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002012bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05302013
2014 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05302015 int mdpIndex = mCurrentFrame.layerToMDP[index];
2016 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2017 info.pipeInfo = new MdpYUVPipeInfo;
2018 info.rot = NULL;
2019 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302020
2021 pipe_info.lIndex = ovutils::OV_INVALID;
2022 pipe_info.rIndex = ovutils::OV_INVALID;
2023
Saurabh Shahc62f3982014-03-05 14:28:26 -08002024 Overlay::PipeSpecs pipeSpecs;
2025 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2026 pipeSpecs.needsScaling = true;
2027 pipeSpecs.dpy = mDpy;
2028 pipeSpecs.fb = false;
2029
2030 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302031 if(pipe_info.lIndex == ovutils::OV_INVALID){
2032 bRet = false;
2033 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2034 __FUNCTION__);
2035 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08002036 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05302037 if(pipe_info.rIndex == ovutils::OV_INVALID){
2038 bRet = false;
2039 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2040 __FUNCTION__);
2041 }
2042 return bRet;
2043}
Sushil Chauhandefd3522014-05-13 18:17:12 -07002044
2045int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2046 int fd = -1;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002047 if (ctx->mPtorInfo.isActive()) {
2048 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002049 if (fd < 0) {
2050 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
Sushil Chauhandefd3522014-05-13 18:17:12 -07002051 }
2052 }
2053 return fd;
2054}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002055//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002056
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002057void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302058 hwc_display_contents_1_t* list) {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002059 //If 4k2k Yuv layer split is possible, and if
2060 //fbz is above 4k2k layer, increment fb zorder by 1
2061 //as we split 4k2k layer and increment zorder for right half
2062 //of the layer
Shalaj Jaina70b4352014-06-15 13:47:47 -07002063 if(!ctx)
2064 return;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002065 if(mCurrentFrame.fbZ >= 0) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302066 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2067 index++) {
2068 if(!mCurrentFrame.isFBComposed[index]) {
2069 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2070 mdpNextZOrder++;
2071 }
2072 mdpNextZOrder++;
2073 hwc_layer_1_t* layer = &list->hwLayers[index];
2074 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302075 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302076 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2077 mCurrentFrame.fbZ += 1;
2078 mdpNextZOrder++;
2079 //As we split 4kx2k yuv layer and program to 2 VG pipes
2080 //(if available) increase mdpcount by 1.
2081 mCurrentFrame.mdpCount++;
2082 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002083 }
2084 }
2085 }
radhakrishnac9a67412013-09-25 17:40:42 +05302086}
2087
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002088/*
2089 * Configures pipe(s) for MDP composition
2090 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002091int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002092 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002093 MdpPipeInfoNonSplit& mdp_info =
2094 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Justin Philipd6166602014-08-12 13:42:21 +05302095 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002096 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahacf10202013-02-26 10:15:15 -08002097 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002098
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002099 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2100 __FUNCTION__, layer, zOrder, dest);
2101
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002102 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002103 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002104}
2105
Saurabh Shah88e4d272013-09-03 13:31:29 -07002106bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002107 hwc_display_contents_1_t* list) {
2108 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002109
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002110 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002111
Jeykumar Sankarancf537002013-01-21 21:19:15 -08002112 hwc_layer_1_t* layer = &list->hwLayers[index];
2113 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302114 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002115 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302116 continue;
2117 }
2118 }
2119
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002120 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002121 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002122 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08002123 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002124 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002125
Saurabh Shahc62f3982014-03-05 14:28:26 -08002126 Overlay::PipeSpecs pipeSpecs;
2127 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2128 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2129 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2130 (qdutils::MDPVersion::getInstance().is8x26() and
2131 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2132 pipeSpecs.dpy = mDpy;
2133 pipeSpecs.fb = false;
Xu Yang1e686f62014-04-08 13:56:47 +08002134 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08002135
Saurabh Shahc62f3982014-03-05 14:28:26 -08002136 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2137
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002138 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002139 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002140 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002141 }
2142 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002143 return true;
2144}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002145
radhakrishnac9a67412013-09-25 17:40:42 +05302146int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2147 PipeLayerPair& PipeLayerPair) {
2148 MdpYUVPipeInfo& mdp_info =
2149 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2150 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302151 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302152 eDest lDest = mdp_info.lIndex;
2153 eDest rDest = mdp_info.rIndex;
2154
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002155 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302156 lDest, rDest, &PipeLayerPair.rot);
2157}
2158
Saurabh Shah88e4d272013-09-03 13:31:29 -07002159bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002160
Raj Kamal4393eaa2014-06-06 13:45:20 +05302161 if(!isEnabled() or !mModeOn) {
2162 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302163 return true;
2164 }
2165
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002166 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002167 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002168 sHandleTimeout = true;
2169 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002170
2171 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002172 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002173
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002174 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2175 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002176 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002177 if(mCurrentFrame.isFBComposed[i]) continue;
2178
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07002179 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002180 private_handle_t *hnd = (private_handle_t *)layer->handle;
2181 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07002182 if (!(layer->flags & HWC_COLOR_FILL)) {
2183 ALOGE("%s handle null", __FUNCTION__);
2184 return false;
2185 }
2186 // No PLAY for Color layer
2187 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2188 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002189 }
2190
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002191 int mdpIndex = mCurrentFrame.layerToMDP[i];
2192
Raj Kamal389d6e32014-08-04 14:43:24 +05302193 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302194 {
2195 MdpYUVPipeInfo& pipe_info =
2196 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2197 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2198 ovutils::eDest indexL = pipe_info.lIndex;
2199 ovutils::eDest indexR = pipe_info.rIndex;
2200 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302201 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302202 if(rot) {
2203 rot->queueBuffer(fd, offset);
2204 fd = rot->getDstMemId();
2205 offset = rot->getDstOffset();
2206 }
2207 if(indexL != ovutils::OV_INVALID) {
2208 ovutils::eDest destL = (ovutils::eDest)indexL;
2209 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2210 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2211 if (!ov.queueBuffer(fd, offset, destL)) {
2212 ALOGE("%s: queueBuffer failed for display:%d",
2213 __FUNCTION__, mDpy);
2214 return false;
2215 }
2216 }
2217
2218 if(indexR != ovutils::OV_INVALID) {
2219 ovutils::eDest destR = (ovutils::eDest)indexR;
2220 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2221 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2222 if (!ov.queueBuffer(fd, offset, destR)) {
2223 ALOGE("%s: queueBuffer failed for display:%d",
2224 __FUNCTION__, mDpy);
2225 return false;
2226 }
2227 }
2228 }
2229 else{
2230 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07002231 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05302232 ovutils::eDest dest = pipe_info.index;
2233 if(dest == ovutils::OV_INVALID) {
2234 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002235 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05302236 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002237
radhakrishnac9a67412013-09-25 17:40:42 +05302238 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2239 continue;
2240 }
2241
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002242 int fd = hnd->fd;
2243 uint32_t offset = (uint32_t)hnd->offset;
2244 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2245 if (!mDpy && (index != -1)) {
Sushil Chauhandefd3522014-05-13 18:17:12 -07002246 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002247 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002248 offset = 0;
Sushil Chauhandefd3522014-05-13 18:17:12 -07002249 }
2250
radhakrishnac9a67412013-09-25 17:40:42 +05302251 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2252 using pipe: %d", __FUNCTION__, layer,
2253 hnd, dest );
2254
radhakrishnac9a67412013-09-25 17:40:42 +05302255 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2256 if(rot) {
2257 if(!rot->queueBuffer(fd, offset))
2258 return false;
2259 fd = rot->getDstMemId();
2260 offset = rot->getDstOffset();
2261 }
2262
2263 if (!ov.queueBuffer(fd, offset, dest)) {
2264 ALOGE("%s: queueBuffer failed for display:%d ",
2265 __FUNCTION__, mDpy);
2266 return false;
2267 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002268 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002269
2270 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002271 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002272 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002273}
2274
Saurabh Shah88e4d272013-09-03 13:31:29 -07002275//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002276
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002277void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05302278 hwc_display_contents_1_t* list){
2279 //if 4kx2k yuv layer is totally present in either in left half
2280 //or right half then try splitting the yuv layer to avoid decimation
radhakrishnac9a67412013-09-25 17:40:42 +05302281 const int lSplit = getLeftSplit(ctx, mDpy);
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302282 if(mCurrentFrame.fbZ >= 0) {
2283 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2284 index++) {
2285 if(!mCurrentFrame.isFBComposed[index]) {
2286 if(mdpNextZOrder == mCurrentFrame.fbZ) {
2287 mdpNextZOrder++;
2288 }
2289 mdpNextZOrder++;
2290 hwc_layer_1_t* layer = &list->hwLayers[index];
2291 private_handle_t *hnd = (private_handle_t *)layer->handle;
Raj Kamal389d6e32014-08-04 14:43:24 +05302292 if(isYUVSplitNeeded(hnd)) {
Dileep Kumar Reddi190dc1c2014-05-22 22:24:53 +05302293 hwc_rect_t dst = layer->displayFrame;
2294 if((dst.left > lSplit) || (dst.right < lSplit)) {
2295 mCurrentFrame.mdpCount += 1;
2296 }
2297 if(mdpNextZOrder <= mCurrentFrame.fbZ)
2298 mCurrentFrame.fbZ += 1;
2299 mdpNextZOrder++;
2300 }
2301 }
Saurabh Shah3d4b8042013-12-10 15:19:17 -08002302 }
radhakrishnac9a67412013-09-25 17:40:42 +05302303 }
2304}
2305
Saurabh Shah88e4d272013-09-03 13:31:29 -07002306bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002307 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002308
Saurabh Shahc62f3982014-03-05 14:28:26 -08002309 const int lSplit = getLeftSplit(ctx, mDpy);
2310 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002311 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002312 pipe_info.lIndex = ovutils::OV_INVALID;
2313 pipe_info.rIndex = ovutils::OV_INVALID;
2314
Saurabh Shahc62f3982014-03-05 14:28:26 -08002315 Overlay::PipeSpecs pipeSpecs;
2316 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2317 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2318 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2319 pipeSpecs.dpy = mDpy;
2320 pipeSpecs.mixer = Overlay::MIXER_LEFT;
2321 pipeSpecs.fb = false;
2322
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002323 // Acquire pipe only for the updating half
2324 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2325 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2326
2327 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002328 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002329 if(pipe_info.lIndex == ovutils::OV_INVALID)
2330 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002331 }
2332
Jeykumar Sankaran6c7eeac2013-11-18 11:19:45 -08002333 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002334 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2335 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002336 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002337 return false;
2338 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002339
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002340 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002341}
2342
Saurabh Shah88e4d272013-09-03 13:31:29 -07002343bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002344 hwc_display_contents_1_t* list) {
2345 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002346
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07002347 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002348
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002349 hwc_layer_1_t* layer = &list->hwLayers[index];
2350 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05302351 hwc_rect_t dst = layer->displayFrame;
2352 const int lSplit = getLeftSplit(ctx, mDpy);
Raj Kamal389d6e32014-08-04 14:43:24 +05302353 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
radhakrishnac9a67412013-09-25 17:40:42 +05302354 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08002355 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05302356 continue;
2357 }
2358 }
2359 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07002360 int mdpIndex = mCurrentFrame.layerToMDP[index];
2361 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07002362 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07002363 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07002364 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002365
Saurabh Shahc62f3982014-03-05 14:28:26 -08002366 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2367 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2368 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002369 return false;
2370 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002371 }
2372 return true;
2373}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07002374
radhakrishnac9a67412013-09-25 17:40:42 +05302375int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2376 PipeLayerPair& PipeLayerPair) {
2377 const int lSplit = getLeftSplit(ctx, mDpy);
2378 hwc_rect_t dst = layer->displayFrame;
2379 if((dst.left > lSplit)||(dst.right < lSplit)){
2380 MdpYUVPipeInfo& mdp_info =
2381 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2382 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302383 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
radhakrishnac9a67412013-09-25 17:40:42 +05302384 eDest lDest = mdp_info.lIndex;
2385 eDest rDest = mdp_info.rIndex;
2386
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002387 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
radhakrishnac9a67412013-09-25 17:40:42 +05302388 lDest, rDest, &PipeLayerPair.rot);
2389 }
2390 else{
2391 return configure(ctx, layer, PipeLayerPair);
2392 }
2393}
2394
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002395/*
2396 * Configures pipe(s) for MDP composition
2397 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07002398int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07002399 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07002400 MdpPipeInfoSplit& mdp_info =
2401 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08002402 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
Justin Philipd6166602014-08-12 13:42:21 +05302403 eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahacf10202013-02-26 10:15:15 -08002404 eDest lDest = mdp_info.lIndex;
2405 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002406
2407 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2408 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2409
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002410 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002411 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002412}
2413
Saurabh Shah88e4d272013-09-03 13:31:29 -07002414bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002415
Raj Kamal4393eaa2014-06-06 13:45:20 +05302416 if(!isEnabled() or !mModeOn) {
2417 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05302418 return true;
2419 }
2420
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002421 // Set the Handle timeout to true for MDP or MIXED composition.
Saurabh Shah59562ff2014-09-30 16:13:12 -07002422 if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08002423 sHandleTimeout = true;
2424 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002425
Naseer Ahmed54821fe2012-11-28 18:44:38 -05002426 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002427 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002428
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002429 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2430 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002431 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002432 if(mCurrentFrame.isFBComposed[i]) continue;
2433
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002434 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08002435 private_handle_t *hnd = (private_handle_t *)layer->handle;
2436 if(!hnd) {
2437 ALOGE("%s handle null", __FUNCTION__);
2438 return false;
2439 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002440
2441 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2442 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002443 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002444
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08002445 int mdpIndex = mCurrentFrame.layerToMDP[i];
2446
Raj Kamal389d6e32014-08-04 14:43:24 +05302447 if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
radhakrishnac9a67412013-09-25 17:40:42 +05302448 {
2449 MdpYUVPipeInfo& pipe_info =
2450 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2451 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2452 ovutils::eDest indexL = pipe_info.lIndex;
2453 ovutils::eDest indexR = pipe_info.rIndex;
2454 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05302455 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05302456 if(rot) {
2457 rot->queueBuffer(fd, offset);
2458 fd = rot->getDstMemId();
2459 offset = rot->getDstOffset();
2460 }
2461 if(indexL != ovutils::OV_INVALID) {
2462 ovutils::eDest destL = (ovutils::eDest)indexL;
2463 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2464 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2465 if (!ov.queueBuffer(fd, offset, destL)) {
2466 ALOGE("%s: queueBuffer failed for display:%d",
2467 __FUNCTION__, mDpy);
2468 return false;
2469 }
2470 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002471
radhakrishnac9a67412013-09-25 17:40:42 +05302472 if(indexR != ovutils::OV_INVALID) {
2473 ovutils::eDest destR = (ovutils::eDest)indexR;
2474 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2475 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2476 if (!ov.queueBuffer(fd, offset, destR)) {
2477 ALOGE("%s: queueBuffer failed for display:%d",
2478 __FUNCTION__, mDpy);
2479 return false;
2480 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002481 }
2482 }
radhakrishnac9a67412013-09-25 17:40:42 +05302483 else{
2484 MdpPipeInfoSplit& pipe_info =
2485 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2486 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07002487
radhakrishnac9a67412013-09-25 17:40:42 +05302488 ovutils::eDest indexL = pipe_info.lIndex;
2489 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002490
radhakrishnac9a67412013-09-25 17:40:42 +05302491 int fd = hnd->fd;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002492 uint32_t offset = (uint32_t)hnd->offset;
2493 int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2494 if (!mDpy && (index != -1)) {
2495 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2496 fd = hnd->fd;
Sushil Chauhan875a92e2014-07-25 12:20:23 -07002497 offset = 0;
Arun Kumar K.Rb2a03b12014-06-03 11:54:10 -07002498 }
radhakrishnac9a67412013-09-25 17:40:42 +05302499
Tatenda Chipeperekwa88fe6352014-04-14 10:36:06 -07002500 if(ctx->mAD->draw(ctx, fd, offset)) {
2501 fd = ctx->mAD->getDstFd();
2502 offset = ctx->mAD->getDstOffset();
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002503 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002504
radhakrishnac9a67412013-09-25 17:40:42 +05302505 if(rot) {
2506 rot->queueBuffer(fd, offset);
2507 fd = rot->getDstMemId();
2508 offset = rot->getDstOffset();
2509 }
2510
2511 //************* play left mixer **********
2512 if(indexL != ovutils::OV_INVALID) {
2513 ovutils::eDest destL = (ovutils::eDest)indexL;
2514 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2515 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
2516 if (!ov.queueBuffer(fd, offset, destL)) {
2517 ALOGE("%s: queueBuffer failed for left mixer",
2518 __FUNCTION__);
2519 return false;
2520 }
2521 }
2522
2523 //************* play right mixer **********
2524 if(indexR != ovutils::OV_INVALID) {
2525 ovutils::eDest destR = (ovutils::eDest)indexR;
2526 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2527 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
2528 if (!ov.queueBuffer(fd, offset, destR)) {
2529 ALOGE("%s: queueBuffer failed for right mixer",
2530 __FUNCTION__);
2531 return false;
2532 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002533 }
2534 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002535
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002536 layerProp[i].mFlags &= ~HWC_MDPCOMP;
2537 }
Saurabh Shahacf10202013-02-26 10:15:15 -08002538
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002539 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002540}
Saurabh Shahab47c692014-02-12 18:45:57 -08002541
2542//================MDPCompSrcSplit==============================================
2543bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08002544 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002545 private_handle_t *hnd = (private_handle_t *)layer->handle;
2546 hwc_rect_t dst = layer->displayFrame;
2547 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2548 pipe_info.lIndex = ovutils::OV_INVALID;
2549 pipe_info.rIndex = ovutils::OV_INVALID;
2550
2551 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2552 //should have a higher priority than the right one. Pipe priorities are
2553 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08002554
Saurabh Shahc62f3982014-03-05 14:28:26 -08002555 Overlay::PipeSpecs pipeSpecs;
2556 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2557 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2558 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2559 pipeSpecs.dpy = mDpy;
2560 pipeSpecs.fb = false;
2561
Saurabh Shahab47c692014-02-12 18:45:57 -08002562 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08002563 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002564 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002565 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002566 }
2567
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002568 /* Use 2 pipes IF
2569 a) Layer's crop width is > 2048 or
2570 b) Layer's dest width > 2048 or
2571 c) On primary, driver has indicated with caps to split always. This is
2572 based on an empirically derived value of panel height. Applied only
2573 if the layer's width is > mixer's width
2574 */
2575
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302576 MDPVersion& mdpHw = MDPVersion::getInstance();
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002577 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
Prabhanjan Kandula5bae9f52014-05-15 16:48:18 +05302578 mdpHw.isSrcSplitAlways();
Saurabh Shah514759d2014-11-11 18:02:24 -08002579 const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2580 const uint32_t dstWidth = dst.right - dst.left;
2581 const uint32_t dstHeight = dst.bottom - dst.top;
2582 const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
Saurabh Shah189f23d2014-09-26 17:21:00 -07002583 crop.right - crop.left;
Saurabh Shah514759d2014-11-11 18:02:24 -08002584 const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2585 crop.bottom - crop.top;
2586 //Approximation to actual clock, ignoring the common factors in pipe and
2587 //mixer cases like line_time
2588 const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2589 const uint32_t mixerClock = lSplit;
Saurabh Shahea7a01d2014-05-22 17:45:36 -07002590
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002591 //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
2592 //pipe line length, we are still using 2 pipes. This is fine just because
2593 //this is source split where destination doesn't matter. Evaluate later to
2594 //see if going through all the calcs to save a pipe is worth it
Saurabh Shah514759d2014-11-11 18:02:24 -08002595 if(dstWidth > mdpHw.getMaxMixerWidth() or
2596 cropWidth > mdpHw.getMaxMixerWidth() or
2597 (primarySplitAlways and
2598 (cropWidth > lSplit or layerClock > mixerClock))) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002599 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08002600 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08002601 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08002602 }
2603
2604 // Return values
2605 // 1 Left pipe is higher priority, do nothing.
2606 // 0 Pipes of same priority.
2607 //-1 Right pipe is of higher priority, needs swap.
2608 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
2609 pipe_info.rIndex) == -1) {
2610 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08002611 }
2612 }
2613
2614 return true;
2615}
2616
Saurabh Shahab47c692014-02-12 18:45:57 -08002617int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2618 PipeLayerPair& PipeLayerPair) {
2619 private_handle_t *hnd = (private_handle_t *)layer->handle;
2620 if(!hnd) {
2621 ALOGE("%s: layer handle is NULL", __FUNCTION__);
2622 return -1;
2623 }
2624 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2625 MdpPipeInfoSplit& mdp_info =
2626 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2627 Rotator **rot = &PipeLayerPair.rot;
2628 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
Saurabh Shahab47c692014-02-12 18:45:57 -08002629 eDest lDest = mdp_info.lIndex;
2630 eDest rDest = mdp_info.rIndex;
2631 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2632 hwc_rect_t dst = layer->displayFrame;
2633 int transform = layer->transform;
2634 eTransform orient = static_cast<eTransform>(transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002635 int rotFlags = ROT_FLAGS_NONE;
2636 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
2637 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2638
2639 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2640 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2641
2642 // Handle R/B swap
2643 if (layer->flags & HWC_FORMAT_RB_SWAP) {
2644 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2645 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2646 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2647 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2648 }
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002649 // update source crop and destination position of AIV video layer.
Ramkumar Radhakrishnanb33f4902014-10-03 16:46:35 -07002650 if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2651 updateCoordinates(ctx, crop, dst, mDpy);
Ramkumar Radhakrishnan9d7bc312014-08-13 19:38:13 -07002652 }
Ramkumar Radhakrishnana5c72872014-08-28 19:04:18 -07002653 /* Calculate the external display position based on MDP downscale,
2654 ActionSafe, and extorientation features. */
2655 calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
Saurabh Shahab47c692014-02-12 18:45:57 -08002656
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002657 int downscale = getRotDownscale(ctx, layer);
Justin Philipd6166602014-08-12 13:42:21 +05302658 eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002659 setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08002660
2661 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2662 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07002663 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08002664 }
2665
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002666 if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002667 (*rot) = ctx->mRotMgr->getNext();
2668 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07002669 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002670 //If the video is using a single pipe, enable BWC
2671 if(rDest == OV_INVALID) {
Saurabh Shahcd018352014-11-11 13:54:19 -08002672 BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2673 mdpFlags);
Saurabh Shah1bd5b6f2014-05-19 12:23:13 -07002674 }
Saurabh Shahab47c692014-02-12 18:45:57 -08002675 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07002676 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08002677 ALOGE("%s: configRotator failed!", __FUNCTION__);
2678 return -1;
2679 }
Saurabh Shah8ec9b5e2014-06-30 14:37:17 -07002680 updateSource(orient, whf, crop, *rot);
Saurabh Shahc46cf9d2014-07-02 15:22:34 -07002681 rotFlags |= ovutils::ROT_PREROTATED;
Saurabh Shahab47c692014-02-12 18:45:57 -08002682 }
2683
2684 //If 2 pipes being used, divide layer into half, crop and dst
2685 hwc_rect_t cropL = crop;
2686 hwc_rect_t cropR = crop;
2687 hwc_rect_t dstL = dst;
2688 hwc_rect_t dstR = dst;
2689 if(lDest != OV_INVALID && rDest != OV_INVALID) {
2690 cropL.right = (crop.right + crop.left) / 2;
2691 cropR.left = cropL.right;
2692 sanitizeSourceCrop(cropL, cropR, hnd);
2693
Saurabh Shahb729b192014-08-15 18:04:24 -07002694 bool cropSwap = false;
Saurabh Shahab47c692014-02-12 18:45:57 -08002695 //Swap crops on H flip since 2 pipes are being used
2696 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2697 hwc_rect_t tmp = cropL;
2698 cropL = cropR;
2699 cropR = tmp;
Saurabh Shahb729b192014-08-15 18:04:24 -07002700 cropSwap = true;
Saurabh Shahab47c692014-02-12 18:45:57 -08002701 }
2702
Saurabh Shahb729b192014-08-15 18:04:24 -07002703 //cropSwap trick: If the src and dst widths are both odd, let us say
2704 //2507, then splitting both into half would cause left width to be 1253
2705 //and right 1254. If crop is swapped because of H flip, this will cause
2706 //left crop width to be 1254, whereas left dst width remains 1253, thus
2707 //inducing a scaling that is unaccounted for. To overcome that we add 1
2708 //to the dst width if there is a cropSwap. So if the original width was
2709 //2507, the left dst width will be 1254. Even if the original width was
2710 //even for ex: 2508, the left dst width will still remain 1254.
2711 dstL.right = (dst.right + dst.left + cropSwap) / 2;
Saurabh Shahab47c692014-02-12 18:45:57 -08002712 dstR.left = dstL.right;
2713 }
2714
2715 //For the mdp, since either we are pre-rotating or MDP does flips
2716 orient = OVERLAY_TRANSFORM_0;
2717 transform = 0;
2718
2719 //configure left pipe
2720 if(lDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002721 PipeArgs pargL(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002722 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2723 (ovutils::eBlending) getBlending(layer->blending));
2724
2725 if(configMdp(ctx->mOverlay, pargL, orient,
2726 cropL, dstL, metadata, lDest) < 0) {
2727 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2728 return -1;
2729 }
2730 }
2731
2732 //configure right pipe
2733 if(rDest != OV_INVALID) {
Saurabh Shah2c8ad052014-08-15 13:27:46 -07002734 PipeArgs pargR(mdpFlags, whf, z,
Saurabh Shahab47c692014-02-12 18:45:57 -08002735 static_cast<eRotFlags>(rotFlags),
2736 layer->planeAlpha,
2737 (ovutils::eBlending) getBlending(layer->blending));
2738 if(configMdp(ctx->mOverlay, pargR, orient,
2739 cropR, dstR, metadata, rDest) < 0) {
2740 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2741 return -1;
2742 }
2743 }
2744
2745 return 0;
2746}
2747
Naseer Ahmed7c958d42012-07-31 18:57:03 -07002748}; //namespace
2749