blob: 40fa624d94c34e97e92c7448fdb0c18fa0ce1aca [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>
Saurabh Shah56f610d2012-08-07 15:27:06 -070022#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070023#include "virtual.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080024#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080025#include "mdp_version.h"
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -070026#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070027#include "hwc_ad.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080028#include <overlayRotator.h>
29
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
Naseer Ahmed7c958d42012-07-31 18:57:03 -070039IdleInvalidator *MDPComp::idleInvalidator = NULL;
40bool 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 Sankaran6a9bb9e2013-08-01 14:19:26 -070045bool MDPComp::sEnablePartialFrameUpdate = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080046int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
radhakrishnac9a67412013-09-25 17:40:42 +053047bool MDPComp::sEnable4k2kYUVSplit = false;
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070048bool MDPComp::sSrcSplitEnabled = false;
Saurabh Shah88e4d272013-09-03 13:31:29 -070049MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070050
Saurabh Shah88e4d272013-09-03 13:31:29 -070051 if(isDisplaySplit(ctx, dpy)) {
Saurabh Shahab47c692014-02-12 18:45:57 -080052 if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -070053 sSrcSplitEnabled = true;
Saurabh Shahab47c692014-02-12 18:45:57 -080054 return new MDPCompSrcSplit(dpy);
55 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070056 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080057 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070058 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080059}
60
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080061MDPComp::MDPComp(int dpy):mDpy(dpy){};
62
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080063void MDPComp::dump(android::String8& buf)
64{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070065 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
66 return;
67
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080068 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070069 (mDpy == 0) ? "\"PRIMARY\"" :
70 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070071 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
72 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080073 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
74 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
75 (mCurrentFrame.needsRedraw? "YES" : "NO"),
76 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
77 dumpsys_log(buf," --------------------------------------------- \n");
78 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
79 dumpsys_log(buf," --------------------------------------------- \n");
80 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
81 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
82 index,
83 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070084 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080085 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070086 (mCurrentFrame.drop[index] ? "DROP" :
87 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080088 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
89 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
90 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080091}
92
93bool MDPComp::init(hwc_context_t *ctx) {
94
95 if(!ctx) {
96 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
97 return false;
98 }
99
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800100 char property[PROPERTY_VALUE_MAX];
101
102 sEnabled = false;
103 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800104 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
105 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800106 sEnabled = true;
107 }
108
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700109 sEnableMixedMode = true;
110 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
111 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
112 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
113 sEnableMixedMode = false;
114 }
115
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800116 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
117 if(atoi(property) != 0)
118 sDebugLogs = true;
119 }
120
Prabhanjan Kandula8e6f9142014-04-21 12:12:38 +0530121 // We read from drivers if panel supports partial updating
122 // and we enable partial update computations if supported.
123 // Keeping this property to disable partial update for
124 // debugging by setting below property to 0 & only 0.
125 property_get("persist.hwc.partialupdate", property, "-1");
126 if((atoi(property) != 0) &&
127 qdutils::MDPVersion::getInstance().isPartialUpdateEnabled()) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700128 sEnablePartialFrameUpdate = true;
129 }
130 ALOGE_IF(isDebug(), "%s: Partial Update applicable?: %d",__FUNCTION__,
131 sEnablePartialFrameUpdate);
132
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800133 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700134 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
135 int val = atoi(property);
136 if(val >= 0)
137 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800138 }
139
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400140 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
141 // Idle invalidation is not necessary on command mode panels
142 long idle_timeout = DEFAULT_IDLE_TIME;
143 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
144 if(atoi(property) != 0)
145 idle_timeout = atoi(property);
146 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800147
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400148 //create Idle Invalidator only when not disabled through property
149 if(idle_timeout != -1)
150 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800151
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400152 if(idleInvalidator == NULL) {
153 ALOGE("%s: failed to instantiate idleInvalidator object",
154 __FUNCTION__);
155 } else {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530156 idleInvalidator->init(timeout_handler, ctx,
157 (unsigned int)idle_timeout);
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400158 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800159 }
radhakrishnac9a67412013-09-25 17:40:42 +0530160
161 if((property_get("debug.mdpcomp.4k2kSplit", property, "0") > 0) &&
162 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
163 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
164 sEnable4k2kYUVSplit = true;
165 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700166 return true;
167}
168
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800169void MDPComp::reset(hwc_context_t *ctx) {
170 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700171 mCurrentFrame.reset(numLayers);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800172 ctx->mOverlay->clear(mDpy);
173 ctx->mLayerRotMap[mDpy]->clear();
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700174}
175
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700176void MDPComp::timeout_handler(void *udata) {
177 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
178
179 if(!ctx) {
180 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
181 return;
182 }
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -0800183 Locker::Autolock _l(ctx->mDrawLock);
184 // Handle timeout event only if the previous composition is MDP or MIXED.
185 if(!sHandleTimeout) {
186 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
187 return;
188 }
Jesse Hall3be78d92012-08-21 15:12:23 -0700189 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700190 ALOGE("%s: HWC proc not registered", __FUNCTION__);
191 return;
192 }
193 sIdleFallBack = true;
194 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700195 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700196}
197
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800198void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800199 hwc_display_contents_1_t* list) {
200 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800201
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800202 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800203 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800204 if(!mCurrentFrame.isFBComposed[index]) {
205 layerProp[index].mFlags |= HWC_MDPCOMP;
206 layer->compositionType = HWC_OVERLAY;
207 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800208 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700209 /* Drop the layer when its already present in FB OR when it lies
210 * outside frame's ROI */
211 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800212 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700213 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800214 }
215 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700216}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500217
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800218void MDPComp::setRedraw(hwc_context_t *ctx,
219 hwc_display_contents_1_t* list) {
220 mCurrentFrame.needsRedraw = false;
221 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
222 (list->flags & HWC_GEOMETRY_CHANGED) ||
223 isSkipPresent(ctx, mDpy)) {
224 mCurrentFrame.needsRedraw = true;
225 }
226}
227
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800228MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700229 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800230}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800231
Saurabh Shahaa236822013-04-24 18:07:26 -0700232void MDPComp::FrameInfo::reset(const int& numLayers) {
233 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800234 if(mdpToLayer[i].pipeInfo) {
235 delete mdpToLayer[i].pipeInfo;
236 mdpToLayer[i].pipeInfo = NULL;
237 //We dont own the rotator
238 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800239 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800240 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800241
242 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
243 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700244 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800245
Saurabh Shahaa236822013-04-24 18:07:26 -0700246 layerCount = numLayers;
247 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800248 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700249 needsRedraw = true;
Saurabh Shahd53bc5f2014-02-05 10:17:43 -0800250 fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800251}
252
Saurabh Shahaa236822013-04-24 18:07:26 -0700253void MDPComp::FrameInfo::map() {
254 // populate layer and MDP maps
255 int mdpIdx = 0;
256 for(int idx = 0; idx < layerCount; idx++) {
257 if(!isFBComposed[idx]) {
258 mdpToLayer[mdpIdx].listIndex = idx;
259 layerToMDP[idx] = mdpIdx++;
260 }
261 }
262}
263
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800264MDPComp::LayerCache::LayerCache() {
265 reset();
266}
267
268void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700269 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530270 memset(&isFBComposed, true, sizeof(isFBComposed));
271 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800272 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700273}
274
275void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +0530276 const int numAppLayers = (int)list->numHwLayers - 1;
Saurabh Shahaa236822013-04-24 18:07:26 -0700277 for(int i = 0; i < numAppLayers; i++) {
278 hnd[i] = list->hwLayers[i].handle;
279 }
280}
281
282void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700283 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530284 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
285 memcpy(&drop, &curFrame.drop, sizeof(drop));
286}
287
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800288bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
289 hwc_display_contents_1_t* list) {
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530290 if(layerCount != curFrame.layerCount)
291 return false;
292 for(int i = 0; i < curFrame.layerCount; i++) {
293 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
294 (curFrame.drop[i] != drop[i])) {
295 return false;
296 }
Jeykumar Sankaran988d3682013-11-15 11:57:16 -0800297 if(curFrame.isFBComposed[i] &&
298 (hnd[i] != list->hwLayers[i].handle)){
299 return false;
300 }
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530301 }
302 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800303}
304
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700305bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
306 private_handle_t *hnd = (private_handle_t *)layer->handle;
307 if((not isYuvBuffer(hnd) and has90Transform(layer)) or
308 (not isValidDimension(ctx,layer))
309 //More conditions here, SKIP, sRGB+Blend etc
310 ) {
311 return false;
312 }
313 return true;
314}
315
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530316bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800317 private_handle_t *hnd = (private_handle_t *)layer->handle;
318
319 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -0700320 if (layer->flags & HWC_COLOR_FILL) {
321 // Color layer
322 return true;
323 }
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800324 ALOGE("%s: layer handle is NULL", __FUNCTION__);
325 return false;
326 }
327
Naseer Ahmede850a802013-09-06 13:12:52 -0400328 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400329 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400330 return false;
331
Saurabh Shah62e1d732013-09-17 10:44:05 -0700332 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700333 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700334 int crop_w = crop.right - crop.left;
335 int crop_h = crop.bottom - crop.top;
336 int dst_w = dst.right - dst.left;
337 int dst_h = dst.bottom - dst.top;
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800338 float w_scale = ((float)crop_w / (float)dst_w);
339 float h_scale = ((float)crop_h / (float)dst_h);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700340
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800341 /* Workaround for MDP HW limitation in DSI command mode panels where
342 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
343 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530344 * There also is a HW limilation in MDP, minimum block size is 2x2
345 * Fallback to GPU if height is less than 2.
346 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800347 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800348 return false;
349
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800350 if((w_scale > 1.0f) || (h_scale > 1.0f)) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700351 const uint32_t maxMDPDownscale =
Saurabh Shah4fdde762013-04-30 18:47:33 -0700352 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800353 const float w_dscale = w_scale;
354 const float h_dscale = h_scale;
355
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800356 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700357
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800358 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700359 /* On targets that doesnt support Decimation (eg.,8x26)
360 * maximum downscale support is overlay pipe downscale.
361 */
362 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
363 h_dscale > maxMDPDownscale)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800364 return false;
365 } else {
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700366 // Decimation on macrotile format layers is not supported.
367 if(isTileRendered(hnd)) {
368 /* MDP can read maximum MAX_DISPLAY_DIM width.
369 * Bail out if
370 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
371 * 2. exceeds maximum downscale limit
372 */
373 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
374 w_dscale > maxMDPDownscale ||
375 h_dscale > maxMDPDownscale) {
376 return false;
377 }
378 } else if(w_dscale > 64 || h_dscale > 64)
Jeykumar Sankaran1706a772013-11-27 12:55:19 -0800379 return false;
380 }
381 } else { //A-family
Manoj Kumar AVM8cbbf7c2014-03-11 01:15:31 -0700382 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
Saurabh Shah4fdde762013-04-30 18:47:33 -0700383 return false;
384 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700385 }
386
Jeykumar Sankaran6cd8e7e2014-01-13 16:01:05 -0800387 if((w_scale < 1.0f) || (h_scale < 1.0f)) {
388 const uint32_t upscale =
389 qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
390 const float w_uscale = 1.0f / w_scale;
391 const float h_uscale = 1.0f / h_scale;
392
393 if(w_uscale > upscale || h_uscale > upscale)
394 return false;
395 }
396
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800397 return true;
398}
399
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800400bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700401 bool ret = true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800402
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800403 if(!isEnabled()) {
404 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700405 ret = false;
Saurabh Shahd4e65852013-06-17 11:33:53 -0700406 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800407 ctx->mVideoTransFlag &&
408 isSecondaryConnected(ctx)) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700409 //1 Padding round to shift pipes across mixers
410 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
411 __FUNCTION__);
412 ret = false;
Ramkumar Radhakrishnan8bb48d32013-12-30 23:11:27 -0800413 } else if(isSecondaryConfiguring(ctx)) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800414 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800415 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700416 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700417 } else if(ctx->isPaddingRound) {
Raj Kamal9ed3d6b2014-02-07 16:15:17 +0530418 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
419 __FUNCTION__,mDpy);
Saurabh Shahaa236822013-04-24 18:07:26 -0700420 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700421 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700422 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800423}
424
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800425/*
426 * 1) Identify layers that are not visible in the updating ROI and drop them
427 * from composition.
428 * 2) If we have a scaling layers which needs cropping against generated ROI.
429 * Reset ROI to full resolution.
430 */
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700431bool MDPComp::validateAndApplyROI(hwc_context_t *ctx,
432 hwc_display_contents_1_t* list, hwc_rect_t roi) {
433 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
434
435 if(!isValidRect(roi))
436 return false;
437
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800438 hwc_rect_t visibleRect = roi;
439
440 for(int i = numAppLayers - 1; i >= 0; i--){
441
442 if(!isValidRect(visibleRect)) {
443 mCurrentFrame.drop[i] = true;
444 mCurrentFrame.dropCount++;
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800445 continue;
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800446 }
447
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700448 const hwc_layer_1_t* layer = &list->hwLayers[i];
449
450 hwc_rect_t dstRect = layer->displayFrame;
Arun Kumar K.R91090c72013-10-28 19:40:18 -0700451 hwc_rect_t srcRect = integerizeSourceCrop(layer->sourceCropf);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700452
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800453 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700454
455 int res_w = res.right - res.left;
456 int res_h = res.bottom - res.top;
457 int dst_w = dstRect.right - dstRect.left;
458 int dst_h = dstRect.bottom - dstRect.top;
459
460 if(!isValidRect(res)) {
461 mCurrentFrame.drop[i] = true;
462 mCurrentFrame.dropCount++;
463 }else {
464 /* Reset frame ROI when any layer which needs scaling also needs ROI
465 * cropping */
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800466 if((res_w != dst_w || res_h != dst_h) && needsScaling (layer)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800467 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700468 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
469 mCurrentFrame.dropCount = 0;
470 return false;
471 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800472
Jeykumar Sankaran0b961452014-01-21 17:26:12 -0800473 /* deduct any opaque region from visibleRect */
474 if (layer->blending == HWC_BLENDING_NONE)
475 visibleRect = deductRect(visibleRect, res);
476 }
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700477 }
478 return true;
479}
480
481void MDPComp::generateROI(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
482 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
483
484 if(!sEnablePartialFrameUpdate) {
485 return;
486 }
487
488 if(mDpy || isDisplaySplit(ctx, mDpy)){
489 ALOGE_IF(isDebug(), "%s: ROI not supported for"
490 "the (1) external / virtual display's (2) dual DSI displays",
491 __FUNCTION__);
492 return;
493 }
494
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800495 if(isSkipPresent(ctx, mDpy))
496 return;
497
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700498 if(list->flags & HWC_GEOMETRY_CHANGED)
499 return;
500
501 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
502 for(int index = 0; index < numAppLayers; index++ ) {
503 if ((mCachedFrame.hnd[index] != list->hwLayers[index].handle) ||
504 isYuvBuffer((private_handle_t *)list->hwLayers[index].handle)) {
505 hwc_rect_t dstRect = list->hwLayers[index].displayFrame;
Arun Kumar K.R91090c72013-10-28 19:40:18 -0700506 hwc_rect_t srcRect = integerizeSourceCrop(
507 list->hwLayers[index].sourceCropf);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700508
509 /* Intersect against display boundaries */
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700510 roi = getUnion(roi, dstRect);
511 }
512 }
513
514 if(!validateAndApplyROI(ctx, list, roi)){
515 roi = (struct hwc_rect) {0, 0,
516 (int)ctx->dpyAttr[mDpy].xres, (int)ctx->dpyAttr[mDpy].yres};
517 }
518
519 ctx->listStats[mDpy].roi.x = roi.left;
520 ctx->listStats[mDpy].roi.y = roi.top;
521 ctx->listStats[mDpy].roi.w = roi.right - roi.left;
522 ctx->listStats[mDpy].roi.h = roi.bottom - roi.top;
523
524 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
525 roi.left, roi.top, roi.right, roi.bottom);
526}
527
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800528/* Checks for conditions where all the layers marked for MDP comp cannot be
529 * bypassed. On such conditions we try to bypass atleast YUV layers */
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800530bool MDPComp::tryFullFrame(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800531 hwc_display_contents_1_t* list){
532
Saurabh Shahaa236822013-04-24 18:07:26 -0700533 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800534 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800535
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700536 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700537 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
538 return false;
539 }
540
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800541 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700542 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
543 __FUNCTION__,
544 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800545 return false;
546 }
547
Arun Kumar K.R2e2871c2014-01-10 12:47:06 -0800548 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
549 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
550 // Disable MDP comp on Secondary when the primary is highres panel and
551 // the secondary is a normal 1080p, because, MDP comp on secondary under
552 // in such usecase, decimation gets used for downscale and there will be
553 // a quality mismatch when there will be a fallback to GPU comp
554 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp",
555 __FUNCTION__);
556 return false;
557 }
558
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800559 // check for action safe flag and downscale mode which requires scaling.
560 if(ctx->dpyAttr[mDpy].mActionSafePresent
561 || ctx->dpyAttr[mDpy].mDownScaleMode) {
562 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
563 return false;
564 }
565
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800566 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800567 hwc_layer_1_t* layer = &list->hwLayers[i];
568 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800569
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700570 if(isYuvBuffer(hnd) && has90Transform(layer)) {
571 if(!canUseRotator(ctx, mDpy)) {
572 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
573 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700574 return false;
575 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800576 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530577
578 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
579 // may not need it if Gfx pre-rotation can handle all flips & rotations
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700580 int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530581 if(qdutils::MDPVersion::getInstance().is8x26() &&
582 (ctx->dpyAttr[mDpy].xres > 1024) &&
Sushil Chauhanfda00fc2014-03-20 11:08:41 -0700583 (transform & HWC_TRANSFORM_FLIP_H) &&
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530584 (!isYuvBuffer(hnd)))
585 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800586 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700587
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700588 if(ctx->mAD->isDoable()) {
589 return false;
590 }
591
Saurabh Shahaa236822013-04-24 18:07:26 -0700592 //If all above hard conditions are met we can do full or partial MDP comp.
593 bool ret = false;
594 if(fullMDPComp(ctx, list)) {
595 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700596 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700597 ret = true;
598 }
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530599
Saurabh Shahaa236822013-04-24 18:07:26 -0700600 return ret;
601}
602
603bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700604 //Will benefit presentation / secondary-only layer.
605 if((mDpy > HWC_DISPLAY_PRIMARY) &&
606 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
607 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
608 return false;
609 }
610
611 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
612 for(int i = 0; i < numAppLayers; i++) {
613 hwc_layer_1_t* layer = &list->hwLayers[i];
614 if(not isSupportedForMDPComp(ctx, layer)) {
615 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
616 return false;
617 }
Yang Xu9c1eb2b2013-11-26 01:28:13 +0800618
619 //For 8x26, if there is only one layer which needs scale for secondary
620 //while no scale for primary display, DMA pipe is occupied by primary.
621 //If need to fall back to GLES composition, virtual display lacks DMA
622 //pipe and error is reported.
623 if(qdutils::MDPVersion::getInstance().is8x26() &&
624 mDpy >= HWC_DISPLAY_EXTERNAL &&
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530625 qhwc::needsScaling(layer))
Yang Xu9c1eb2b2013-11-26 01:28:13 +0800626 return false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700627 }
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800628
Saurabh Shahaa236822013-04-24 18:07:26 -0700629 mCurrentFrame.fbCount = 0;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700630 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
631 sizeof(mCurrentFrame.isFBComposed));
632 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
633 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700634
radhakrishnac9a67412013-09-25 17:40:42 +0530635 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800636 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530637 }
638
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800639 if(!postHeuristicsHandling(ctx, list)) {
640 ALOGD_IF(isDebug(), "post heuristic handling failed");
641 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700642 return false;
643 }
644
Saurabh Shahaa236822013-04-24 18:07:26 -0700645 return true;
646}
647
648bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
649{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700650 if(!sEnableMixedMode) {
651 //Mixed mode is disabled. No need to even try caching.
652 return false;
653 }
654
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700655 bool ret = false;
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800656 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800657 ret = loadBasedComp(ctx, list) or
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800658 cacheBasedComp(ctx, list);
659 } else {
660 ret = cacheBasedComp(ctx, list) or
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800661 loadBasedComp(ctx, list);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700662 }
663
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700664 return ret;
665}
666
667bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
668 hwc_display_contents_1_t* list) {
669 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700670 mCurrentFrame.reset(numAppLayers);
671 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700672
673 //If an MDP marked layer is unsupported cannot do partial MDP Comp
674 for(int i = 0; i < numAppLayers; i++) {
675 if(!mCurrentFrame.isFBComposed[i]) {
676 hwc_layer_1_t* layer = &list->hwLayers[i];
677 if(not isSupportedForMDPComp(ctx, layer)) {
678 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
679 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800680 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700681 return false;
682 }
683 }
684 }
685
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700686 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530687 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700688 if(!ret) {
689 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800690 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700691 return false;
692 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700693
694 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700695
radhakrishnac9a67412013-09-25 17:40:42 +0530696 if(sEnable4k2kYUVSplit){
Saurabh Shah3d4b8042013-12-10 15:19:17 -0800697 adjustForSourceSplit(ctx, list);
radhakrishnac9a67412013-09-25 17:40:42 +0530698 }
699
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700700 //Will benefit cases where a video has non-updating background.
701 if((mDpy > HWC_DISPLAY_PRIMARY) and
702 (mdpCount > MAX_SEC_LAYERS)) {
703 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800704 reset(ctx);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700705 return false;
706 }
707
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800708 if(!postHeuristicsHandling(ctx, list)) {
709 ALOGD_IF(isDebug(), "post heuristic handling failed");
710 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700711 return false;
712 }
713
Saurabh Shahaa236822013-04-24 18:07:26 -0700714 return true;
715}
716
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800717bool MDPComp::loadBasedComp(hwc_context_t *ctx,
Saurabh Shahb772ae32013-11-18 15:40:02 -0800718 hwc_display_contents_1_t* list) {
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -0800719 if(not isLoadBasedCompDoable(ctx)) {
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800720 return false;
721 }
722
Saurabh Shahb772ae32013-11-18 15:40:02 -0800723 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800724 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
725 const int stagesForMDP = min(sMaxPipesPerMixer,
726 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
Saurabh Shahf2de00f2013-12-11 17:52:53 -0800727
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800728 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
729 int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
730 int lastMDPSupportedIndex = numAppLayers;
731 int dropCount = 0;
Saurabh Shahb772ae32013-11-18 15:40:02 -0800732
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800733 //Find the minimum MDP batch size
734 for(int i = 0; i < numAppLayers;i++) {
735 if(mCurrentFrame.drop[i]) {
736 dropCount++;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -0800737 continue;
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800738 }
739 hwc_layer_1_t* layer = &list->hwLayers[i];
740 if(not isSupportedForMDPComp(ctx, layer)) {
741 lastMDPSupportedIndex = i;
742 mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
743 fbBatchSize = numNonDroppedLayers - mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -0800744 break;
Saurabh Shahb772ae32013-11-18 15:40:02 -0800745 }
Saurabh Shahb772ae32013-11-18 15:40:02 -0800746 }
747
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800748 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
749 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
750 mCurrentFrame.dropCount);
751
752 //Start at a point where the fb batch should at least have 2 layers, for
753 //this mode to be justified.
754 while(fbBatchSize < 2) {
755 ++fbBatchSize;
756 --mdpBatchSize;
Jeykumar Sankaran846e2792014-01-23 21:59:58 -0800757 }
Saurabh Shahb772ae32013-11-18 15:40:02 -0800758
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800759 //If there are no layers for MDP, this mode doesnt make sense.
760 if(mdpBatchSize < 1) {
761 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
762 __FUNCTION__);
Saurabh Shahb772ae32013-11-18 15:40:02 -0800763 return false;
764 }
765
Saurabh Shahbe7bd322014-02-20 16:18:45 -0800766 mCurrentFrame.reset(numAppLayers);
767
768 //Try with successively smaller mdp batch sizes until we succeed or reach 1
769 while(mdpBatchSize > 0) {
770 //Mark layers for MDP comp
771 int mdpBatchLeft = mdpBatchSize;
772 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
773 if(mCurrentFrame.drop[i]) {
774 continue;
775 }
776 mCurrentFrame.isFBComposed[i] = false;
777 --mdpBatchLeft;
778 }
779
780 mCurrentFrame.fbZ = mdpBatchSize;
781 mCurrentFrame.fbCount = fbBatchSize;
782 mCurrentFrame.mdpCount = mdpBatchSize;
783
784 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
785 __FUNCTION__, mdpBatchSize, fbBatchSize,
786 mCurrentFrame.dropCount);
787
788 if(postHeuristicsHandling(ctx, list)) {
789 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
790 __FUNCTION__);
791 return true;
792 }
793
794 reset(ctx);
795 --mdpBatchSize;
796 ++fbBatchSize;
797 }
798
799 return false;
Saurabh Shahb772ae32013-11-18 15:40:02 -0800800}
801
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -0800802bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
Prabhanjan Kandula3dbbd882013-12-11 14:43:46 +0530803 if(mDpy or isSecurePresent(ctx, mDpy) or
804 isYuvPresent(ctx, mDpy)) {
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700805 return false;
806 }
807 return true;
808}
809
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800810bool MDPComp::tryVideoOnly(hwc_context_t *ctx,
811 hwc_display_contents_1_t* list) {
812 const bool secureOnly = true;
813 return videoOnlyComp(ctx, list, not secureOnly) or
814 videoOnlyComp(ctx, list, secureOnly);
815}
816
817bool MDPComp::videoOnlyComp(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700818 hwc_display_contents_1_t* list, bool secureOnly) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700819 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700820
Saurabh Shahaa236822013-04-24 18:07:26 -0700821 mCurrentFrame.reset(numAppLayers);
Jeykumar Sankaraneb3a5e22014-04-08 16:07:55 -0700822 mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700823 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700824 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700825
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800826 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
827 reset(ctx);
Saurabh Shahaa236822013-04-24 18:07:26 -0700828 return false;
829 }
830
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -0800831 /* Bail out if we are processing only secured video layers
832 * and we dont have any */
833 if(!isSecurePresent(ctx, mDpy) && secureOnly){
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800834 reset(ctx);
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -0800835 return false;
836 }
837
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800838 if(mCurrentFrame.fbCount)
839 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700840
Saurabh Shahdf4741d2013-12-12 16:40:28 -0800841 if(sEnable4k2kYUVSplit){
842 adjustForSourceSplit(ctx, list);
843 }
844
845 if(!postHeuristicsHandling(ctx, list)) {
846 ALOGD_IF(isDebug(), "post heuristic handling failed");
847 reset(ctx);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700848 return false;
849 }
850
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800851 return true;
852}
853
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800854/* Checks for conditions where YUV layers cannot be bypassed */
855bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -0700856 if(isSkipLayer(layer)) {
Saurabh Shahe2474082013-05-15 16:32:13 -0700857 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800858 return false;
859 }
860
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700861 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
862 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
863 return false;
864 }
865
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800866 if(isSecuring(ctx, layer)) {
867 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
868 return false;
869 }
870
Saurabh Shah4fdde762013-04-30 18:47:33 -0700871 if(!isValidDimension(ctx, layer)) {
872 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
873 __FUNCTION__);
874 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800875 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700876
Naseer Ahmeddc61a972013-07-10 17:50:54 -0400877 if(layer->planeAlpha < 0xFF) {
878 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
879 in video only mode",
880 __FUNCTION__);
881 return false;
882 }
883
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800884 return true;
885}
886
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530887/* starts at fromIndex and check for each layer to find
888 * if it it has overlapping with any Updating layer above it in zorder
889 * till the end of the batch. returns true if it finds any intersection */
890bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
891 int fromIndex, int toIndex) {
892 for(int i = fromIndex; i < toIndex; i++) {
893 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
894 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
895 return false;
896 }
897 }
898 }
899 return true;
900}
901
902/* Checks if given layer at targetLayerIndex has any
903 * intersection with all the updating layers in beween
904 * fromIndex and toIndex. Returns true if it finds intersectiion */
905bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
906 int fromIndex, int toIndex, int targetLayerIndex) {
907 for(int i = fromIndex; i <= toIndex; i++) {
908 if(!mCurrentFrame.isFBComposed[i]) {
909 if(areLayersIntersecting(&list->hwLayers[i],
910 &list->hwLayers[targetLayerIndex])) {
911 return true;
912 }
913 }
914 }
915 return false;
916}
917
918int MDPComp::getBatch(hwc_display_contents_1_t* list,
919 int& maxBatchStart, int& maxBatchEnd,
920 int& maxBatchCount) {
921 int i = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530922 int fbZOrder =-1;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -0800923 int droppedLayerCt = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530924 while (i < mCurrentFrame.layerCount) {
925 int batchCount = 0;
926 int batchStart = i;
927 int batchEnd = i;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -0800928 /* Adjust batch Z order with the dropped layers so far */
929 int fbZ = batchStart - droppedLayerCt;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530930 int firstZReverseIndex = -1;
Prabhanjan Kandula0ed2cc92013-12-06 12:39:04 +0530931 int updatingLayersAbove = 0;//Updating layer count in middle of batch
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530932 while(i < mCurrentFrame.layerCount) {
933 if(!mCurrentFrame.isFBComposed[i]) {
934 if(!batchCount) {
935 i++;
936 break;
937 }
938 updatingLayersAbove++;
939 i++;
940 continue;
941 } else {
942 if(mCurrentFrame.drop[i]) {
943 i++;
Jeykumar Sankaran9502f352014-01-20 12:25:32 -0800944 droppedLayerCt++;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530945 continue;
946 } else if(updatingLayersAbove <= 0) {
947 batchCount++;
948 batchEnd = i;
949 i++;
950 continue;
951 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
952
953 // We have a valid updating layer already. If layer-i not
954 // have overlapping with all updating layers in between
955 // batch-start and i, then we can add layer i to batch.
956 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
957 batchCount++;
958 batchEnd = i;
959 i++;
960 continue;
961 } else if(canPushBatchToTop(list, batchStart, i)) {
962 //If All the non-updating layers with in this batch
963 //does not have intersection with the updating layers
964 //above in z-order, then we can safely move the batch to
965 //higher z-order. Increment fbZ as it is moving up.
966 if( firstZReverseIndex < 0) {
967 firstZReverseIndex = i;
968 }
969 batchCount++;
970 batchEnd = i;
971 fbZ += updatingLayersAbove;
972 i++;
973 updatingLayersAbove = 0;
974 continue;
975 } else {
976 //both failed.start the loop again from here.
977 if(firstZReverseIndex >= 0) {
978 i = firstZReverseIndex;
979 }
980 break;
981 }
982 }
983 }
984 }
985 if(batchCount > maxBatchCount) {
986 maxBatchCount = batchCount;
987 maxBatchStart = batchStart;
988 maxBatchEnd = batchEnd;
989 fbZOrder = fbZ;
990 }
991 }
992 return fbZOrder;
993}
994
995bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
996 hwc_display_contents_1_t* list) {
997 /* Idea is to keep as many non-updating(cached) layers in FB and
998 * send rest of them through MDP. This is done in 2 steps.
999 * 1. Find the maximum contiguous batch of non-updating layers.
1000 * 2. See if we can improve this batch size for caching by adding
1001 * opaque layers around the batch, if they don't have
1002 * any overlapping with the updating layers in between.
1003 * NEVER mark an updating layer for caching.
1004 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001005
1006 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001007 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001008 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301009 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001010
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001011 /* Nothing is cached. No batching needed */
1012 if(mCurrentFrame.fbCount == 0) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001013 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -07001014 }
Saurabh Shahd53bc5f2014-02-05 10:17:43 -08001015
1016 /* No MDP comp layers, try to use other comp modes */
1017 if(mCurrentFrame.mdpCount == 0) {
1018 return false;
Saurabh Shahaa236822013-04-24 18:07:26 -07001019 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001020
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301021 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001022
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301023 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001024 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001025 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001026 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301027 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001028 if(!mCurrentFrame.drop[i]){
1029 //If an unsupported layer is being attempted to
1030 //be pulled out we should fail
1031 if(not isSupportedForMDPComp(ctx, layer)) {
1032 return false;
1033 }
1034 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001035 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001036 }
1037 }
1038
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301039 // update the frame data
1040 mCurrentFrame.fbZ = fbZ;
1041 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001042 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001043 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001044
1045 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301046 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001047
1048 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001049}
Saurabh Shah85234ec2013-04-12 17:09:00 -07001050
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001051void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001052 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001053 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001054 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001055
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001056 for(int i = 0; i < numAppLayers; i++) {
1057 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001058 if(!mCurrentFrame.drop[i])
1059 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001060 mCurrentFrame.isFBComposed[i] = true;
1061 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -07001062 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001063 }
1064 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001065
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001066 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001067 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1068 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001069
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001070 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1071 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1072 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001073}
1074
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001075void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1076 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001077 int nYuvCount = ctx->listStats[mDpy].yuvCount;
1078 for(int index = 0;index < nYuvCount; index++){
1079 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1080 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1081
1082 if(!isYUVDoable(ctx, layer)) {
1083 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1084 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1085 mCurrentFrame.fbCount++;
1086 }
1087 } else {
1088 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001089 private_handle_t *hnd = (private_handle_t *)layer->handle;
1090 if(!secureOnly || isSecureBuffer(hnd)) {
1091 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1092 mCurrentFrame.fbCount--;
1093 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001094 }
1095 }
1096 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001097
1098 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001099 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1100 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001101 mCurrentFrame.fbCount);
1102}
1103
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301104hwc_rect_t MDPComp::getUpdatingFBRect(hwc_display_contents_1_t* list){
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001105 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001106
1107 /* Update only the region of FB needed for composition */
1108 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1109 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1110 hwc_layer_1_t* layer = &list->hwLayers[i];
1111 hwc_rect_t dst = layer->displayFrame;
1112 fbRect = getUnion(fbRect, dst);
1113 }
1114 }
1115 return fbRect;
1116}
1117
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001118bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1119 hwc_display_contents_1_t* list) {
1120
1121 //Capability checks
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301122 if(!resourceCheck()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001123 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1124 return false;
1125 }
1126
1127 //Limitations checks
1128 if(!hwLimitationsCheck(ctx, list)) {
1129 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1130 return false;
1131 }
1132
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001133 //Configure framebuffer first if applicable
1134 if(mCurrentFrame.fbZ >= 0) {
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301135 hwc_rect_t fbRect = getUpdatingFBRect(list);
Jeykumar Sankaranc2d78d82014-02-14 14:55:29 -08001136 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1137 {
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001138 ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1139 __FUNCTION__);
1140 return false;
1141 }
1142 }
1143
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001144 mCurrentFrame.map();
1145
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001146 if(!allocLayerPipes(ctx, list)) {
1147 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001148 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001149 }
1150
1151 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001152 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001153 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001154 int mdpIndex = mCurrentFrame.layerToMDP[index];
1155 hwc_layer_1_t* layer = &list->hwLayers[index];
1156
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301157 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1158 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1159 mdpNextZOrder++;
1160 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001161 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1162 cur_pipe->zOrder = mdpNextZOrder++;
1163
radhakrishnac9a67412013-09-25 17:40:42 +05301164 private_handle_t *hnd = (private_handle_t *)layer->handle;
1165 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1166 if(configure4k2kYuv(ctx, layer,
1167 mCurrentFrame.mdpToLayer[mdpIndex])
1168 != 0 ){
1169 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1170 for layer %d",__FUNCTION__, index);
1171 return false;
1172 }
1173 else{
1174 mdpNextZOrder++;
1175 }
1176 continue;
1177 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001178 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1179 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
radhakrishnac9a67412013-09-25 17:40:42 +05301180 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001181 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001182 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001183 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001184 }
1185
Saurabh Shaha36be922013-12-16 18:18:39 -08001186 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1187 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1188 ,__FUNCTION__, mDpy);
1189 return false;
1190 }
1191
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001192 setRedraw(ctx, list);
Saurabh Shahaa236822013-04-24 18:07:26 -07001193 return true;
1194}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001195
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301196bool MDPComp::resourceCheck() {
Saurabh Shah173f4242013-11-20 09:50:12 -08001197 const bool fbUsed = mCurrentFrame.fbCount;
1198 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1199 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1200 return false;
1201 }
Saurabh Shah173f4242013-11-20 09:50:12 -08001202 return true;
1203}
1204
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301205bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1206 hwc_display_contents_1_t* list) {
1207
1208 //A-family hw limitation:
1209 //If a layer need alpha scaling, MDP can not support.
1210 if(ctx->mMDP.version < qdutils::MDSS_V5) {
1211 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1212 if(!mCurrentFrame.isFBComposed[i] &&
1213 isAlphaScaled( &list->hwLayers[i])) {
1214 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1215 return false;
1216 }
1217 }
1218 }
1219
1220 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1221 //If multiple layers requires downscaling and also they are overlapping
1222 //fall back to GPU since MDSS can not handle it.
1223 if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1224 qdutils::MDPVersion::getInstance().is8x26()) {
1225 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1226 hwc_layer_1_t* botLayer = &list->hwLayers[i];
1227 if(!mCurrentFrame.isFBComposed[i] &&
1228 isDownscaleRequired(botLayer)) {
1229 //if layer-i is marked for MDP and needs downscaling
1230 //check if any MDP layer on top of i & overlaps with layer-i
1231 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1232 hwc_layer_1_t* topLayer = &list->hwLayers[j];
1233 if(!mCurrentFrame.isFBComposed[j] &&
1234 isDownscaleRequired(topLayer)) {
1235 hwc_rect_t r = getIntersection(botLayer->displayFrame,
1236 topLayer->displayFrame);
1237 if(isValidRect(r))
1238 return false;
1239 }
1240 }
1241 }
1242 }
1243 }
1244 return true;
1245}
1246
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001247int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001248 int ret = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -07001249 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001250
Raj Kamal9ed3d6b2014-02-07 16:15:17 +05301251 //Do not cache the information for next draw cycle.
1252 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
1253 ALOGI("%s: Unsupported layer count for mdp composition",
1254 __FUNCTION__);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001255 mCachedFrame.reset();
1256 return -1;
1257 }
1258
Saurabh Shahb39f8152013-08-22 10:21:44 -07001259 //reset old data
1260 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001261 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1262 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301263
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001264 // Detect the start of animation and fall back to GPU only once to cache
1265 // all the layers in FB and display FB content untill animation completes.
1266 if(ctx->listStats[mDpy].isDisplayAnimating) {
1267 mCurrentFrame.needsRedraw = false;
1268 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
1269 mCurrentFrame.needsRedraw = true;
1270 ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
1271 }
1272 setMDPCompLayerFlags(ctx, list);
1273 mCachedFrame.updateCounts(mCurrentFrame);
1274 ret = -1;
1275 return ret;
1276 } else {
1277 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
1278 }
1279
Saurabh Shahb39f8152013-08-22 10:21:44 -07001280 //Hard conditions, if not met, cannot do MDP comp
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001281 if(isFrameDoable(ctx)) {
1282 generateROI(ctx, list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001283
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001284 if(tryFullFrame(ctx, list) || tryVideoOnly(ctx, list)) {
1285 setMDPCompLayerFlags(ctx, list);
1286 } else {
1287 reset(ctx);
1288 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1289 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001290 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001291 }
1292 } else {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001293 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1294 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001295 ret = -1;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001296 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001297
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001298 if(isDebug()) {
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001299 ALOGD("GEOMETRY change: %d",
1300 (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001301 android::String8 sDump("");
1302 dump(sDump);
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001303 ALOGD("%s",sDump.string());
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001304 }
1305
Saurabh Shahdf4741d2013-12-12 16:40:28 -08001306 mCachedFrame.cacheAll(list);
1307 mCachedFrame.updateCounts(mCurrentFrame);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001308 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001309}
1310
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001311bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
radhakrishnac9a67412013-09-25 17:40:42 +05301312
1313 bool bRet = true;
radhakrishnac9a67412013-09-25 17:40:42 +05301314 int mdpIndex = mCurrentFrame.layerToMDP[index];
1315 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
1316 info.pipeInfo = new MdpYUVPipeInfo;
1317 info.rot = NULL;
1318 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301319
1320 pipe_info.lIndex = ovutils::OV_INVALID;
1321 pipe_info.rIndex = ovutils::OV_INVALID;
1322
Saurabh Shahc62f3982014-03-05 14:28:26 -08001323 Overlay::PipeSpecs pipeSpecs;
1324 pipeSpecs.formatClass = Overlay::FORMAT_YUV;
1325 pipeSpecs.needsScaling = true;
1326 pipeSpecs.dpy = mDpy;
1327 pipeSpecs.fb = false;
1328
1329 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301330 if(pipe_info.lIndex == ovutils::OV_INVALID){
1331 bRet = false;
1332 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
1333 __FUNCTION__);
1334 }
Saurabh Shahc62f3982014-03-05 14:28:26 -08001335 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
radhakrishnac9a67412013-09-25 17:40:42 +05301336 if(pipe_info.rIndex == ovutils::OV_INVALID){
1337 bRet = false;
1338 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
1339 __FUNCTION__);
1340 }
1341 return bRet;
1342}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001343//=============MDPCompNonSplit==================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001344
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001345void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001346 hwc_display_contents_1_t*) {
radhakrishnac9a67412013-09-25 17:40:42 +05301347 //As we split 4kx2k yuv layer and program to 2 VG pipes
1348 //(if available) increase mdpcount accordingly
1349 mCurrentFrame.mdpCount += ctx->listStats[mDpy].yuv4k2kCount;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001350
1351 //If 4k2k Yuv layer split is possible, and if
1352 //fbz is above 4k2k layer, increment fb zorder by 1
1353 //as we split 4k2k layer and increment zorder for right half
1354 //of the layer
1355 if(mCurrentFrame.fbZ >= 0) {
1356 int n4k2kYuvCount = ctx->listStats[mDpy].yuv4k2kCount;
1357 for(int index = 0; index < n4k2kYuvCount; index++){
1358 int n4k2kYuvIndex =
1359 ctx->listStats[mDpy].yuv4k2kIndices[index];
Dileep Kumar Reddi4cff9282014-04-01 12:57:08 +05301360 if(mCurrentFrame.fbZ >= n4k2kYuvIndex){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001361 mCurrentFrame.fbZ += 1;
1362 }
1363 }
1364 }
radhakrishnac9a67412013-09-25 17:40:42 +05301365}
1366
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001367/*
1368 * Configures pipe(s) for MDP composition
1369 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001370int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001371 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001372 MdpPipeInfoNonSplit& mdp_info =
1373 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001374 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1375 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1376 eIsFg isFg = IS_FG_OFF;
1377 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001378
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001379 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1380 __FUNCTION__, layer, zOrder, dest);
1381
Saurabh Shah88e4d272013-09-03 13:31:29 -07001382 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001383 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001384}
1385
Saurabh Shah88e4d272013-09-03 13:31:29 -07001386bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001387 hwc_display_contents_1_t* list) {
1388 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001389
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001390 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001391
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001392 hwc_layer_1_t* layer = &list->hwLayers[index];
1393 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301394 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001395 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301396 continue;
1397 }
1398 }
1399
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001400 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001401 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001402 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001403 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001404 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001405
Saurabh Shahc62f3982014-03-05 14:28:26 -08001406 Overlay::PipeSpecs pipeSpecs;
1407 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1408 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1409 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
1410 (qdutils::MDPVersion::getInstance().is8x26() and
1411 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
1412 pipeSpecs.dpy = mDpy;
1413 pipeSpecs.fb = false;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001414
Saurabh Shahc62f3982014-03-05 14:28:26 -08001415 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
1416
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001417 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001418 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001419 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001420 }
1421 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001422 return true;
1423}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001424
radhakrishnac9a67412013-09-25 17:40:42 +05301425int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1426 PipeLayerPair& PipeLayerPair) {
1427 MdpYUVPipeInfo& mdp_info =
1428 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1429 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1430 eIsFg isFg = IS_FG_OFF;
1431 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1432 eDest lDest = mdp_info.lIndex;
1433 eDest rDest = mdp_info.rIndex;
1434
1435 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1436 lDest, rDest, &PipeLayerPair.rot);
1437}
1438
Saurabh Shah88e4d272013-09-03 13:31:29 -07001439bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001440
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001441 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001442 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1443 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -08001444 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001445
1446 if(!ctx || !list) {
1447 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001448 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001449 }
1450
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301451 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
1452 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
1453 return true;
1454 }
1455
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001456 // Set the Handle timeout to true for MDP or MIXED composition.
1457 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1458 sHandleTimeout = true;
1459 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001460
1461 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001462 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001463
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001464 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1465 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001466 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001467 if(mCurrentFrame.isFBComposed[i]) continue;
1468
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001469 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001470 private_handle_t *hnd = (private_handle_t *)layer->handle;
1471 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001472 if (!(layer->flags & HWC_COLOR_FILL)) {
1473 ALOGE("%s handle null", __FUNCTION__);
1474 return false;
1475 }
1476 // No PLAY for Color layer
1477 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1478 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001479 }
1480
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001481 int mdpIndex = mCurrentFrame.layerToMDP[i];
1482
radhakrishnac9a67412013-09-25 17:40:42 +05301483 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1484 {
1485 MdpYUVPipeInfo& pipe_info =
1486 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1487 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1488 ovutils::eDest indexL = pipe_info.lIndex;
1489 ovutils::eDest indexR = pipe_info.rIndex;
1490 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301491 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301492 if(rot) {
1493 rot->queueBuffer(fd, offset);
1494 fd = rot->getDstMemId();
1495 offset = rot->getDstOffset();
1496 }
1497 if(indexL != ovutils::OV_INVALID) {
1498 ovutils::eDest destL = (ovutils::eDest)indexL;
1499 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1500 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1501 if (!ov.queueBuffer(fd, offset, destL)) {
1502 ALOGE("%s: queueBuffer failed for display:%d",
1503 __FUNCTION__, mDpy);
1504 return false;
1505 }
1506 }
1507
1508 if(indexR != ovutils::OV_INVALID) {
1509 ovutils::eDest destR = (ovutils::eDest)indexR;
1510 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1511 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1512 if (!ov.queueBuffer(fd, offset, destR)) {
1513 ALOGE("%s: queueBuffer failed for display:%d",
1514 __FUNCTION__, mDpy);
1515 return false;
1516 }
1517 }
1518 }
1519 else{
1520 MdpPipeInfoNonSplit& pipe_info =
Saurabh Shah88e4d272013-09-03 13:31:29 -07001521 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
radhakrishnac9a67412013-09-25 17:40:42 +05301522 ovutils::eDest dest = pipe_info.index;
1523 if(dest == ovutils::OV_INVALID) {
1524 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001525 return false;
radhakrishnac9a67412013-09-25 17:40:42 +05301526 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001527
radhakrishnac9a67412013-09-25 17:40:42 +05301528 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1529 continue;
1530 }
1531
1532 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1533 using pipe: %d", __FUNCTION__, layer,
1534 hnd, dest );
1535
1536 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301537 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301538
1539 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1540 if(rot) {
1541 if(!rot->queueBuffer(fd, offset))
1542 return false;
1543 fd = rot->getDstMemId();
1544 offset = rot->getDstOffset();
1545 }
1546
1547 if (!ov.queueBuffer(fd, offset, dest)) {
1548 ALOGE("%s: queueBuffer failed for display:%d ",
1549 __FUNCTION__, mDpy);
1550 return false;
1551 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001552 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001553
1554 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001555 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001556 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001557}
1558
Saurabh Shah88e4d272013-09-03 13:31:29 -07001559//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001560
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001561void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
radhakrishnac9a67412013-09-25 17:40:42 +05301562 hwc_display_contents_1_t* list){
1563 //if 4kx2k yuv layer is totally present in either in left half
1564 //or right half then try splitting the yuv layer to avoid decimation
1565 int n4k2kYuvCount = ctx->listStats[mDpy].yuv4k2kCount;
1566 const int lSplit = getLeftSplit(ctx, mDpy);
1567 for(int index = 0; index < n4k2kYuvCount; index++){
1568 int n4k2kYuvIndex = ctx->listStats[mDpy].yuv4k2kIndices[index];
1569 hwc_layer_1_t* layer = &list->hwLayers[n4k2kYuvIndex];
1570 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001571 if((dst.left > lSplit) || (dst.right < lSplit)) {
radhakrishnac9a67412013-09-25 17:40:42 +05301572 mCurrentFrame.mdpCount += 1;
1573 }
Dileep Kumar Reddi4cff9282014-04-01 12:57:08 +05301574 if(mCurrentFrame.fbZ >= n4k2kYuvIndex){
Saurabh Shah3d4b8042013-12-10 15:19:17 -08001575 mCurrentFrame.fbZ += 1;
1576 }
radhakrishnac9a67412013-09-25 17:40:42 +05301577 }
1578}
1579
Saurabh Shah88e4d272013-09-03 13:31:29 -07001580bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001581 MdpPipeInfoSplit& pipe_info) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001582
Saurabh Shahc62f3982014-03-05 14:28:26 -08001583 const int lSplit = getLeftSplit(ctx, mDpy);
1584 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001585 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001586 pipe_info.lIndex = ovutils::OV_INVALID;
1587 pipe_info.rIndex = ovutils::OV_INVALID;
1588
Saurabh Shahc62f3982014-03-05 14:28:26 -08001589 Overlay::PipeSpecs pipeSpecs;
1590 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1591 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1592 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
1593 pipeSpecs.dpy = mDpy;
1594 pipeSpecs.mixer = Overlay::MIXER_LEFT;
1595 pipeSpecs.fb = false;
1596
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001597 if (dst.left < lSplit) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001598 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001599 if(pipe_info.lIndex == ovutils::OV_INVALID)
1600 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001601 }
1602
1603 if(dst.right > lSplit) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001604 pipeSpecs.mixer = Overlay::MIXER_RIGHT;
1605 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001606 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001607 return false;
1608 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001609
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001610 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001611}
1612
Saurabh Shah88e4d272013-09-03 13:31:29 -07001613bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001614 hwc_display_contents_1_t* list) {
1615 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001616
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001617 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001618
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001619 hwc_layer_1_t* layer = &list->hwLayers[index];
1620 private_handle_t *hnd = (private_handle_t *)layer->handle;
radhakrishnac9a67412013-09-25 17:40:42 +05301621 hwc_rect_t dst = layer->displayFrame;
1622 const int lSplit = getLeftSplit(ctx, mDpy);
1623 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){
1624 if((dst.left > lSplit)||(dst.right < lSplit)){
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001625 if(allocSplitVGPipesfor4k2k(ctx, index)){
radhakrishnac9a67412013-09-25 17:40:42 +05301626 continue;
1627 }
1628 }
1629 }
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001630 int mdpIndex = mCurrentFrame.layerToMDP[index];
1631 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001632 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001633 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001634 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001635
Saurabh Shahc62f3982014-03-05 14:28:26 -08001636 if(!acquireMDPPipes(ctx, layer, pipe_info)) {
1637 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
1638 __FUNCTION__);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001639 return false;
1640 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001641 }
1642 return true;
1643}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001644
radhakrishnac9a67412013-09-25 17:40:42 +05301645int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
1646 PipeLayerPair& PipeLayerPair) {
1647 const int lSplit = getLeftSplit(ctx, mDpy);
1648 hwc_rect_t dst = layer->displayFrame;
1649 if((dst.left > lSplit)||(dst.right < lSplit)){
1650 MdpYUVPipeInfo& mdp_info =
1651 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
1652 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1653 eIsFg isFg = IS_FG_OFF;
1654 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1655 eDest lDest = mdp_info.lIndex;
1656 eDest rDest = mdp_info.rIndex;
1657
1658 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg,
1659 lDest, rDest, &PipeLayerPair.rot);
1660 }
1661 else{
1662 return configure(ctx, layer, PipeLayerPair);
1663 }
1664}
1665
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001666/*
1667 * Configures pipe(s) for MDP composition
1668 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001669int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001670 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001671 MdpPipeInfoSplit& mdp_info =
1672 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001673 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1674 eIsFg isFg = IS_FG_OFF;
1675 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1676 eDest lDest = mdp_info.lIndex;
1677 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001678
1679 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
1680 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
1681
Saurabh Shah88e4d272013-09-03 13:31:29 -07001682 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001683 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001684}
1685
Saurabh Shah88e4d272013-09-03 13:31:29 -07001686bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001687
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001688 if(!isEnabled()) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001689 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1690 return true;
1691 }
1692
1693 if(!ctx || !list) {
1694 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001695 return false;
1696 }
1697
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301698 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
1699 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
1700 return true;
1701 }
1702
Ramkumar Radhakrishnan92abb4f2014-02-06 21:31:29 -08001703 // Set the Handle timeout to true for MDP or MIXED composition.
1704 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
1705 sHandleTimeout = true;
1706 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001707
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001708 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001709 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001710
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001711 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1712 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001713 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001714 if(mCurrentFrame.isFBComposed[i]) continue;
1715
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001716 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001717 private_handle_t *hnd = (private_handle_t *)layer->handle;
1718 if(!hnd) {
1719 ALOGE("%s handle null", __FUNCTION__);
1720 return false;
1721 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001722
1723 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1724 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001725 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001726
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001727 int mdpIndex = mCurrentFrame.layerToMDP[i];
1728
radhakrishnac9a67412013-09-25 17:40:42 +05301729 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit)
1730 {
1731 MdpYUVPipeInfo& pipe_info =
1732 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1733 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1734 ovutils::eDest indexL = pipe_info.lIndex;
1735 ovutils::eDest indexR = pipe_info.rIndex;
1736 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301737 uint32_t offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301738 if(rot) {
1739 rot->queueBuffer(fd, offset);
1740 fd = rot->getDstMemId();
1741 offset = rot->getDstOffset();
1742 }
1743 if(indexL != ovutils::OV_INVALID) {
1744 ovutils::eDest destL = (ovutils::eDest)indexL;
1745 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1746 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1747 if (!ov.queueBuffer(fd, offset, destL)) {
1748 ALOGE("%s: queueBuffer failed for display:%d",
1749 __FUNCTION__, mDpy);
1750 return false;
1751 }
1752 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001753
radhakrishnac9a67412013-09-25 17:40:42 +05301754 if(indexR != ovutils::OV_INVALID) {
1755 ovutils::eDest destR = (ovutils::eDest)indexR;
1756 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1757 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1758 if (!ov.queueBuffer(fd, offset, destR)) {
1759 ALOGE("%s: queueBuffer failed for display:%d",
1760 __FUNCTION__, mDpy);
1761 return false;
1762 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -07001763 }
1764 }
radhakrishnac9a67412013-09-25 17:40:42 +05301765 else{
1766 MdpPipeInfoSplit& pipe_info =
1767 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1768 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07001769
radhakrishnac9a67412013-09-25 17:40:42 +05301770 ovutils::eDest indexL = pipe_info.lIndex;
1771 ovutils::eDest indexR = pipe_info.rIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001772
radhakrishnac9a67412013-09-25 17:40:42 +05301773 int fd = hnd->fd;
Praveena Pachipulusud9443c72014-02-17 10:42:28 +05301774 int offset = (uint32_t)hnd->offset;
radhakrishnac9a67412013-09-25 17:40:42 +05301775
1776 if(ctx->mAD->isModeOn()) {
1777 if(ctx->mAD->draw(ctx, fd, offset)) {
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -08001778 fd = ctx->mAD->getDstFd();
1779 offset = ctx->mAD->getDstOffset();
radhakrishnac9a67412013-09-25 17:40:42 +05301780 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001781 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001782
radhakrishnac9a67412013-09-25 17:40:42 +05301783 if(rot) {
1784 rot->queueBuffer(fd, offset);
1785 fd = rot->getDstMemId();
1786 offset = rot->getDstOffset();
1787 }
1788
1789 //************* play left mixer **********
1790 if(indexL != ovutils::OV_INVALID) {
1791 ovutils::eDest destL = (ovutils::eDest)indexL;
1792 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1793 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
1794 if (!ov.queueBuffer(fd, offset, destL)) {
1795 ALOGE("%s: queueBuffer failed for left mixer",
1796 __FUNCTION__);
1797 return false;
1798 }
1799 }
1800
1801 //************* play right mixer **********
1802 if(indexR != ovutils::OV_INVALID) {
1803 ovutils::eDest destR = (ovutils::eDest)indexR;
1804 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1805 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
1806 if (!ov.queueBuffer(fd, offset, destR)) {
1807 ALOGE("%s: queueBuffer failed for right mixer",
1808 __FUNCTION__);
1809 return false;
1810 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001811 }
1812 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001813
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001814 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1815 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001816
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001817 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001818}
Saurabh Shahab47c692014-02-12 18:45:57 -08001819
1820//================MDPCompSrcSplit==============================================
1821bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
Saurabh Shahc62f3982014-03-05 14:28:26 -08001822 MdpPipeInfoSplit& pipe_info) {
Saurabh Shahab47c692014-02-12 18:45:57 -08001823 private_handle_t *hnd = (private_handle_t *)layer->handle;
1824 hwc_rect_t dst = layer->displayFrame;
1825 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
1826 pipe_info.lIndex = ovutils::OV_INVALID;
1827 pipe_info.rIndex = ovutils::OV_INVALID;
1828
1829 //If 2 pipes are staged on a single stage of a mixer, then the left pipe
1830 //should have a higher priority than the right one. Pipe priorities are
1831 //starting with VG0, VG1 ... , RGB0 ..., DMA1
Saurabh Shahab47c692014-02-12 18:45:57 -08001832
Saurabh Shahc62f3982014-03-05 14:28:26 -08001833 Overlay::PipeSpecs pipeSpecs;
1834 pipeSpecs.formatClass = isYuvBuffer(hnd) ?
1835 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
1836 pipeSpecs.needsScaling = qhwc::needsScaling(layer);
1837 pipeSpecs.dpy = mDpy;
1838 pipeSpecs.fb = false;
1839
Saurabh Shahab47c692014-02-12 18:45:57 -08001840 //1 pipe by default for a layer
Saurabh Shahc62f3982014-03-05 14:28:26 -08001841 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08001842 if(pipe_info.lIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001843 return false;
Saurabh Shahab47c692014-02-12 18:45:57 -08001844 }
1845
1846 //If layer's crop width or dest width > 2048, use 2 pipes
1847 if((dst.right - dst.left) > qdutils::MAX_DISPLAY_DIM or
1848 (crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001849 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
Saurabh Shahab47c692014-02-12 18:45:57 -08001850 if(pipe_info.rIndex == ovutils::OV_INVALID) {
Saurabh Shahc62f3982014-03-05 14:28:26 -08001851 return false;
Saurabh Shahdd8237a2014-02-28 14:29:09 -08001852 }
1853
1854 // Return values
1855 // 1 Left pipe is higher priority, do nothing.
1856 // 0 Pipes of same priority.
1857 //-1 Right pipe is of higher priority, needs swap.
1858 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
1859 pipe_info.rIndex) == -1) {
1860 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
Saurabh Shahab47c692014-02-12 18:45:57 -08001861 }
1862 }
1863
1864 return true;
1865}
1866
Saurabh Shahab47c692014-02-12 18:45:57 -08001867int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
1868 PipeLayerPair& PipeLayerPair) {
1869 private_handle_t *hnd = (private_handle_t *)layer->handle;
1870 if(!hnd) {
1871 ALOGE("%s: layer handle is NULL", __FUNCTION__);
1872 return -1;
1873 }
1874 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
1875 MdpPipeInfoSplit& mdp_info =
1876 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
1877 Rotator **rot = &PipeLayerPair.rot;
1878 eZorder z = static_cast<eZorder>(mdp_info.zOrder);
1879 eIsFg isFg = IS_FG_OFF;
1880 eDest lDest = mdp_info.lIndex;
1881 eDest rDest = mdp_info.rIndex;
1882 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
1883 hwc_rect_t dst = layer->displayFrame;
1884 int transform = layer->transform;
1885 eTransform orient = static_cast<eTransform>(transform);
1886 const int downscale = 0;
1887 int rotFlags = ROT_FLAGS_NONE;
1888 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
1889 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
1890
1891 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
1892 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
1893
1894 // Handle R/B swap
1895 if (layer->flags & HWC_FORMAT_RB_SWAP) {
1896 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
1897 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
1898 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
1899 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
1900 }
1901
Saurabh Shah97e2d802014-04-14 18:03:54 -07001902 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1903 setMdpFlags(layer, mdpFlags, 0, transform);
Saurabh Shahab47c692014-02-12 18:45:57 -08001904
1905 if(lDest != OV_INVALID && rDest != OV_INVALID) {
1906 //Enable overfetch
Saurabh Shah97e2d802014-04-14 18:03:54 -07001907 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
Saurabh Shahab47c692014-02-12 18:45:57 -08001908 }
1909
1910 if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
1911 (*rot) = ctx->mRotMgr->getNext();
1912 if((*rot) == NULL) return -1;
Saurabh Shah39240c92014-03-31 10:31:42 -07001913 ctx->mLayerRotMap[mDpy]->add(layer, *rot);
Saurabh Shahab47c692014-02-12 18:45:57 -08001914 //Configure rotator for pre-rotation
Saurabh Shah97e2d802014-04-14 18:03:54 -07001915 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
Saurabh Shahab47c692014-02-12 18:45:57 -08001916 ALOGE("%s: configRotator failed!", __FUNCTION__);
1917 return -1;
1918 }
Saurabh Shahab47c692014-02-12 18:45:57 -08001919 whf.format = (*rot)->getDstFormat();
1920 updateSource(orient, whf, crop);
1921 rotFlags |= ROT_PREROTATED;
1922 }
1923
1924 //If 2 pipes being used, divide layer into half, crop and dst
1925 hwc_rect_t cropL = crop;
1926 hwc_rect_t cropR = crop;
1927 hwc_rect_t dstL = dst;
1928 hwc_rect_t dstR = dst;
1929 if(lDest != OV_INVALID && rDest != OV_INVALID) {
1930 cropL.right = (crop.right + crop.left) / 2;
1931 cropR.left = cropL.right;
1932 sanitizeSourceCrop(cropL, cropR, hnd);
1933
1934 //Swap crops on H flip since 2 pipes are being used
1935 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
1936 hwc_rect_t tmp = cropL;
1937 cropL = cropR;
1938 cropR = tmp;
1939 }
1940
1941 dstL.right = (dst.right + dst.left) / 2;
1942 dstR.left = dstL.right;
1943 }
1944
1945 //For the mdp, since either we are pre-rotating or MDP does flips
1946 orient = OVERLAY_TRANSFORM_0;
1947 transform = 0;
1948
1949 //configure left pipe
1950 if(lDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07001951 PipeArgs pargL(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08001952 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
1953 (ovutils::eBlending) getBlending(layer->blending));
1954
1955 if(configMdp(ctx->mOverlay, pargL, orient,
1956 cropL, dstL, metadata, lDest) < 0) {
1957 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
1958 return -1;
1959 }
1960 }
1961
1962 //configure right pipe
1963 if(rDest != OV_INVALID) {
Saurabh Shah97e2d802014-04-14 18:03:54 -07001964 PipeArgs pargR(mdpFlags, whf, z, isFg,
Saurabh Shahab47c692014-02-12 18:45:57 -08001965 static_cast<eRotFlags>(rotFlags),
1966 layer->planeAlpha,
1967 (ovutils::eBlending) getBlending(layer->blending));
1968 if(configMdp(ctx->mOverlay, pargR, orient,
1969 cropR, dstR, metadata, rDest) < 0) {
1970 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
1971 return -1;
1972 }
1973 }
1974
1975 return 0;
1976}
1977
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001978}; //namespace
1979