blob: 788a8906a065e09f17a92b4ffc0ba70240db9116 [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08002 * Copyright (C) 2012-2013, 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;
41bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050042bool MDPComp::sEnabled = false;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -070043bool MDPComp::sEnableMixedMode = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080044int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah8c5c8522013-08-29 17:32:49 -070045float MDPComp::sMaxBw = 2.3f;
46uint32_t MDPComp::sCompBytesClaimed = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070047
Saurabh Shah88e4d272013-09-03 13:31:29 -070048MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
49 if(isDisplaySplit(ctx, dpy)) {
50 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080051 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070052 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080053}
54
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080055MDPComp::MDPComp(int dpy):mDpy(dpy){};
56
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080057void MDPComp::dump(android::String8& buf)
58{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070059 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
60 return;
61
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080062 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070063 (mDpy == 0) ? "\"PRIMARY\"" :
64 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070065 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
66 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080067 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
68 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
69 (mCurrentFrame.needsRedraw? "YES" : "NO"),
70 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
71 dumpsys_log(buf," --------------------------------------------- \n");
72 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
73 dumpsys_log(buf," --------------------------------------------- \n");
74 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
75 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
76 index,
77 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
78 mCurrentFrame.layerToMDP[index],
79 (mCurrentFrame.isFBComposed[index] ?
80 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE") : "MDP"),
81 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
82 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
83 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080084}
85
86bool MDPComp::init(hwc_context_t *ctx) {
87
88 if(!ctx) {
89 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
90 return false;
91 }
92
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080093 char property[PROPERTY_VALUE_MAX];
94
95 sEnabled = false;
96 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080097 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
98 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080099 sEnabled = true;
100 }
101
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700102 sEnableMixedMode = true;
103 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
104 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
105 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
106 sEnableMixedMode = false;
107 }
108
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800109 sDebugLogs = false;
110 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
111 if(atoi(property) != 0)
112 sDebugLogs = true;
113 }
114
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800115 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700116 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
117 int val = atoi(property);
118 if(val >= 0)
119 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800120 }
121
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700122 if(property_get("debug.mdpcomp.bw", property, "0") > 0) {
123 float val = atof(property);
124 if(val > 0.0f) {
125 sMaxBw = val;
126 }
127 }
128
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400129 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
130 // Idle invalidation is not necessary on command mode panels
131 long idle_timeout = DEFAULT_IDLE_TIME;
132 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
133 if(atoi(property) != 0)
134 idle_timeout = atoi(property);
135 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800136
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400137 //create Idle Invalidator only when not disabled through property
138 if(idle_timeout != -1)
139 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800140
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400141 if(idleInvalidator == NULL) {
142 ALOGE("%s: failed to instantiate idleInvalidator object",
143 __FUNCTION__);
144 } else {
145 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
146 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800147 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700148 return true;
149}
150
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700151void MDPComp::reset(const int& numLayers, hwc_display_contents_1_t* list) {
152 mCurrentFrame.reset(numLayers);
153 mCachedFrame.cacheAll(list);
154 mCachedFrame.updateCounts(mCurrentFrame);
155}
156
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700157void MDPComp::timeout_handler(void *udata) {
158 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
159
160 if(!ctx) {
161 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
162 return;
163 }
164
Jesse Hall3be78d92012-08-21 15:12:23 -0700165 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700166 ALOGE("%s: HWC proc not registered", __FUNCTION__);
167 return;
168 }
169 sIdleFallBack = true;
170 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700171 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700172}
173
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800174void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800175 hwc_display_contents_1_t* list) {
176 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800177
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800178 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800179 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800180 if(!mCurrentFrame.isFBComposed[index]) {
181 layerProp[index].mFlags |= HWC_MDPCOMP;
182 layer->compositionType = HWC_OVERLAY;
183 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800184 } else {
185 if(!mCurrentFrame.needsRedraw)
186 layer->compositionType = HWC_OVERLAY;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800187 }
188 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700189}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500190
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800191MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700192 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800193}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800194
Saurabh Shahaa236822013-04-24 18:07:26 -0700195void MDPComp::FrameInfo::reset(const int& numLayers) {
196 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800197 if(mdpToLayer[i].pipeInfo) {
198 delete mdpToLayer[i].pipeInfo;
199 mdpToLayer[i].pipeInfo = NULL;
200 //We dont own the rotator
201 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800202 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800203 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800204
205 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
206 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700207 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800208
Saurabh Shahaa236822013-04-24 18:07:26 -0700209 layerCount = numLayers;
210 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800211 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700212 needsRedraw = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800213 fbZ = 0;
214}
215
Saurabh Shahaa236822013-04-24 18:07:26 -0700216void MDPComp::FrameInfo::map() {
217 // populate layer and MDP maps
218 int mdpIdx = 0;
219 for(int idx = 0; idx < layerCount; idx++) {
220 if(!isFBComposed[idx]) {
221 mdpToLayer[mdpIdx].listIndex = idx;
222 layerToMDP[idx] = mdpIdx++;
223 }
224 }
225}
226
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800227MDPComp::LayerCache::LayerCache() {
228 reset();
229}
230
231void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700232 memset(&hnd, 0, sizeof(hnd));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800233 mdpCount = 0;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700234 fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800235 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700236 fbZ = -1;
237}
238
239void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
240 const int numAppLayers = list->numHwLayers - 1;
241 for(int i = 0; i < numAppLayers; i++) {
242 hnd[i] = list->hwLayers[i].handle;
243 }
244}
245
246void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
247 mdpCount = curFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700248 fbCount = curFrame.fbCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700249 layerCount = curFrame.layerCount;
250 fbZ = curFrame.fbZ;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800251}
252
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700253bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
254 private_handle_t *hnd = (private_handle_t *)layer->handle;
255 if((not isYuvBuffer(hnd) and has90Transform(layer)) or
256 (not isValidDimension(ctx,layer))
257 //More conditions here, SKIP, sRGB+Blend etc
258 ) {
259 return false;
260 }
261 return true;
262}
263
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530264bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Saurabh Shah4fdde762013-04-30 18:47:33 -0700265 const int dpy = HWC_DISPLAY_PRIMARY;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800266 private_handle_t *hnd = (private_handle_t *)layer->handle;
267
268 if(!hnd) {
269 ALOGE("%s: layer handle is NULL", __FUNCTION__);
270 return false;
271 }
272
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800273 int hw_w = ctx->dpyAttr[mDpy].xres;
274 int hw_h = ctx->dpyAttr[mDpy].yres;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800275
Saurabh Shah4fdde762013-04-30 18:47:33 -0700276 hwc_rect_t crop = layer->sourceCrop;
277 hwc_rect_t dst = layer->displayFrame;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800278
279 if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
Saurabh Shah4fdde762013-04-30 18:47:33 -0700280 hwc_rect_t scissor = {0, 0, hw_w, hw_h };
281 qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800282 }
283
Saurabh Shah4fdde762013-04-30 18:47:33 -0700284 int crop_w = crop.right - crop.left;
285 int crop_h = crop.bottom - crop.top;
286 int dst_w = dst.right - dst.left;
287 int dst_h = dst.bottom - dst.top;
288 float w_dscale = ceilf((float)crop_w / (float)dst_w);
289 float h_dscale = ceilf((float)crop_h / (float)dst_h);
290
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800291 /* Workaround for MDP HW limitation in DSI command mode panels where
292 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
293 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530294 * There also is a HW limilation in MDP, minimum block size is 2x2
295 * Fallback to GPU if height is less than 2.
296 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800297 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800298 return false;
299
Saurabh Shah4fdde762013-04-30 18:47:33 -0700300 const uint32_t downscale =
301 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
302 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
303 /* Workaround for downscales larger than 4x.
304 * Will be removed once decimator block is enabled for MDSS
305 */
306 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
307 if(crop_w > MAX_DISPLAY_DIM || w_dscale > downscale ||
308 h_dscale > downscale)
309 return false;
310 } else {
311 if(w_dscale > 64 || h_dscale > 64)
312 return false;
313 }
314 } else { //A-family
315 if(w_dscale > downscale || h_dscale > downscale)
316 return false;
317 }
318
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800319 return true;
320}
321
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700322ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type,
323 int mixer) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800324 overlay::Overlay& ov = *ctx->mOverlay;
325 ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
326
327 switch(type) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800328 case MDPCOMP_OV_DMA:
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700329 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy, mixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800330 if(mdp_pipe != ovutils::OV_INVALID) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800331 return mdp_pipe;
332 }
333 case MDPCOMP_OV_ANY:
334 case MDPCOMP_OV_RGB:
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700335 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy, mixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800336 if(mdp_pipe != ovutils::OV_INVALID) {
337 return mdp_pipe;
338 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800339
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800340 if(type == MDPCOMP_OV_RGB) {
341 //Requested only for RGB pipe
342 break;
343 }
344 case MDPCOMP_OV_VG:
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700345 return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy, mixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800346 default:
347 ALOGE("%s: Invalid pipe type",__FUNCTION__);
348 return ovutils::OV_INVALID;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800349 };
350 return ovutils::OV_INVALID;
351}
352
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800353bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700354 bool ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700355 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800356
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800357 if(!isEnabled()) {
358 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700359 ret = false;
Saurabh Shahd4e65852013-06-17 11:33:53 -0700360 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
Jeykumar Sankaran27dee262013-08-01 17:09:54 -0700361 ctx->mVideoTransFlag && ctx->mVirtualDisplay->isConnected()) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700362 //1 Padding round to shift pipes across mixers
363 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
364 __FUNCTION__);
365 ret = false;
Jeykumar Sankaran27dee262013-08-01 17:09:54 -0700366 } else if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isConfiguring ||
367 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isConfiguring) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800368 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800369 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700370 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700371 } else if(ctx->isPaddingRound) {
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700372 ctx->isPaddingRound = false;
373 ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700374 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700375 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700376 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800377}
378
379/* Checks for conditions where all the layers marked for MDP comp cannot be
380 * bypassed. On such conditions we try to bypass atleast YUV layers */
381bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
382 hwc_display_contents_1_t* list){
383
Saurabh Shahaa236822013-04-24 18:07:26 -0700384 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800385
Saurabh Shah2d998a92013-05-14 17:55:58 -0700386 if(sIdleFallBack) {
387 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
388 return false;
389 }
390
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800391 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700392 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
393 __FUNCTION__,
394 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800395 return false;
396 }
397
Saurabh Shah9f084ad2013-05-02 11:28:09 -0700398 if(ctx->listStats[mDpy].needsAlphaScale
399 && ctx->mMDP.version < qdutils::MDSS_V5) {
400 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
401 return false;
402 }
403
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800404 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800405 hwc_layer_1_t* layer = &list->hwLayers[i];
406 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800407
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700408 if(isYuvBuffer(hnd) && has90Transform(layer)) {
409 if(!canUseRotator(ctx, mDpy)) {
410 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
411 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700412 return false;
413 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800414 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530415
416 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
417 // may not need it if Gfx pre-rotation can handle all flips & rotations
418 if(qdutils::MDPVersion::getInstance().is8x26() &&
419 (ctx->dpyAttr[mDpy].xres > 1024) &&
420 (layer->transform & HWC_TRANSFORM_FLIP_H) &&
421 (!isYuvBuffer(hnd)))
422 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800423 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700424
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700425 if(ctx->mAD->isDoable()) {
426 return false;
427 }
428
Saurabh Shahaa236822013-04-24 18:07:26 -0700429 //If all above hard conditions are met we can do full or partial MDP comp.
430 bool ret = false;
431 if(fullMDPComp(ctx, list)) {
432 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700433 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700434 ret = true;
435 }
436 return ret;
437}
438
439bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700440 //Will benefit presentation / secondary-only layer.
441 if((mDpy > HWC_DISPLAY_PRIMARY) &&
442 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
443 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
444 return false;
445 }
446
447 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
448 for(int i = 0; i < numAppLayers; i++) {
449 hwc_layer_1_t* layer = &list->hwLayers[i];
450 if(not isSupportedForMDPComp(ctx, layer)) {
451 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
452 return false;
453 }
454 }
455
Saurabh Shahaa236822013-04-24 18:07:26 -0700456 //Setup mCurrentFrame
457 mCurrentFrame.mdpCount = mCurrentFrame.layerCount;
458 mCurrentFrame.fbCount = 0;
459 mCurrentFrame.fbZ = -1;
460 memset(&mCurrentFrame.isFBComposed, 0, sizeof(mCurrentFrame.isFBComposed));
461
462 int mdpCount = mCurrentFrame.mdpCount;
463 if(mdpCount > sMaxPipesPerMixer) {
464 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
465 return false;
466 }
467
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700468 if(!arePipesAvailable(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700469 return false;
470 }
471
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700472 uint32_t size = calcMDPBytesRead(ctx, list);
473 if(!bandwidthCheck(ctx, size)) {
474 ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
475 return false;
476 }
477
Saurabh Shahaa236822013-04-24 18:07:26 -0700478 return true;
479}
480
481bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
482{
483 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700484
485 if(!sEnableMixedMode) {
486 //Mixed mode is disabled. No need to even try caching.
487 return false;
488 }
489
Saurabh Shahaa236822013-04-24 18:07:26 -0700490 //Setup mCurrentFrame
491 mCurrentFrame.reset(numAppLayers);
492 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700493
494 //If an MDP marked layer is unsupported cannot do partial MDP Comp
495 for(int i = 0; i < numAppLayers; i++) {
496 if(!mCurrentFrame.isFBComposed[i]) {
497 hwc_layer_1_t* layer = &list->hwLayers[i];
498 if(not isSupportedForMDPComp(ctx, layer)) {
499 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
500 __FUNCTION__);
501 return false;
502 }
503 }
504 }
505
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700506 updateYUV(ctx, list, false /*secure only*/);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700507 bool ret = batchLayers(ctx, list); //sets up fbZ also
508 if(!ret) {
509 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
510 return false;
511 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700512
513 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700514
515 //Will benefit cases where a video has non-updating background.
516 if((mDpy > HWC_DISPLAY_PRIMARY) and
517 (mdpCount > MAX_SEC_LAYERS)) {
518 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
519 return false;
520 }
521
Saurabh Shahaa236822013-04-24 18:07:26 -0700522 if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used
523 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
524 return false;
525 }
526
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700527 if(!arePipesAvailable(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700528 return false;
529 }
530
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700531 uint32_t size = calcMDPBytesRead(ctx, list);
532 if(!bandwidthCheck(ctx, size)) {
533 ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
534 return false;
535 }
536
Saurabh Shahaa236822013-04-24 18:07:26 -0700537 return true;
538}
539
540bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700541 hwc_display_contents_1_t* list, bool secureOnly) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700542 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
543 mCurrentFrame.reset(numAppLayers);
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700544 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700545 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700546 int fbNeeded = int(mCurrentFrame.fbCount != 0);
547
548 if(!isYuvPresent(ctx, mDpy)) {
549 return false;
550 }
551
Saurabh Shah4fdde762013-04-30 18:47:33 -0700552 if(!mdpCount)
553 return false;
554
Saurabh Shahaa236822013-04-24 18:07:26 -0700555 if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
556 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
557 return false;
558 }
559
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700560 if(!arePipesAvailable(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700561 return false;
562 }
563
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700564 uint32_t size = calcMDPBytesRead(ctx, list);
565 if(!bandwidthCheck(ctx, size)) {
566 ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
567 return false;
568 }
569
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800570 return true;
571}
572
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800573/* Checks for conditions where YUV layers cannot be bypassed */
574bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Saurabh Shahe2474082013-05-15 16:32:13 -0700575 bool extAnimBlockFeature = mDpy && ctx->listStats[mDpy].isDisplayAnimating;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800576
Saurabh Shahe2474082013-05-15 16:32:13 -0700577 if(isSkipLayer(layer) && !extAnimBlockFeature) {
578 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800579 return false;
580 }
581
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700582 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
583 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
584 return false;
585 }
586
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800587 if(isSecuring(ctx, layer)) {
588 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
589 return false;
590 }
591
Saurabh Shah4fdde762013-04-30 18:47:33 -0700592 if(!isValidDimension(ctx, layer)) {
593 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
594 __FUNCTION__);
595 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800596 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700597
Naseer Ahmeddc61a972013-07-10 17:50:54 -0400598 if(layer->planeAlpha < 0xFF) {
599 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
600 in video only mode",
601 __FUNCTION__);
602 return false;
603 }
604
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800605 return true;
606}
607
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700608bool MDPComp::batchLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800609 /* Idea is to keep as many contiguous non-updating(cached) layers in FB and
610 * send rest of them through MDP. NEVER mark an updating layer for caching.
611 * But cached ones can be marked for MDP*/
612
613 int maxBatchStart = -1;
614 int maxBatchCount = 0;
615
616 /* All or Nothing is cached. No batching needed */
Saurabh Shahaa236822013-04-24 18:07:26 -0700617 if(!mCurrentFrame.fbCount) {
618 mCurrentFrame.fbZ = -1;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700619 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -0700620 }
621 if(!mCurrentFrame.mdpCount) {
622 mCurrentFrame.fbZ = 0;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700623 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -0700624 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800625
626 /* Search for max number of contiguous (cached) layers */
627 int i = 0;
628 while (i < mCurrentFrame.layerCount) {
629 int count = 0;
630 while(mCurrentFrame.isFBComposed[i] && i < mCurrentFrame.layerCount) {
631 count++; i++;
632 }
633 if(count > maxBatchCount) {
634 maxBatchCount = count;
635 maxBatchStart = i - count;
Saurabh Shahaa236822013-04-24 18:07:26 -0700636 mCurrentFrame.fbZ = maxBatchStart;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800637 }
638 if(i < mCurrentFrame.layerCount) i++;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800639 }
640
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800641 /* reset rest of the layers for MDP comp */
642 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700643 hwc_layer_1_t* layer = &list->hwLayers[i];
644 if(i != maxBatchStart) {
645 //If an unsupported layer is being attempted to be pulled out we
646 //should fail
647 if(not isSupportedForMDPComp(ctx, layer)) {
648 return false;
649 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800650 mCurrentFrame.isFBComposed[i] = false;
651 } else {
652 i += maxBatchCount;
653 }
654 }
655
656 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700657 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
658 mCurrentFrame.fbCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800659
660 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
661 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700662
663 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800664}
Saurabh Shah85234ec2013-04-12 17:09:00 -0700665
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800666void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700667 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800668 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700669 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800670
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800671 for(int i = 0; i < numAppLayers; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700672 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800673 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700674 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800675 mCurrentFrame.isFBComposed[i] = true;
676 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -0700677 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800678 mCachedFrame.hnd[i] = list->hwLayers[i].handle;
679 }
680 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700681
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700682 mCurrentFrame.fbCount = fbCount;
683 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount;
684
685 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d",__FUNCTION__,
686 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800687}
688
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700689void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
690 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800691 int nYuvCount = ctx->listStats[mDpy].yuvCount;
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -0700692 if(!nYuvCount && mDpy) {
693 //Reset "No animation on external display" related parameters.
694 ctx->mPrevCropVideo.left = ctx->mPrevCropVideo.top =
695 ctx->mPrevCropVideo.right = ctx->mPrevCropVideo.bottom = 0;
696 ctx->mPrevDestVideo.left = ctx->mPrevDestVideo.top =
697 ctx->mPrevDestVideo.right = ctx->mPrevDestVideo.bottom = 0;
698 ctx->mPrevTransformVideo = 0;
699 return;
700 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800701 for(int index = 0;index < nYuvCount; index++){
702 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
703 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
704
705 if(!isYUVDoable(ctx, layer)) {
706 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
707 mCurrentFrame.isFBComposed[nYuvIndex] = true;
708 mCurrentFrame.fbCount++;
709 }
710 } else {
711 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700712 private_handle_t *hnd = (private_handle_t *)layer->handle;
713 if(!secureOnly || isSecureBuffer(hnd)) {
714 mCurrentFrame.isFBComposed[nYuvIndex] = false;
715 mCurrentFrame.fbCount--;
716 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800717 }
718 }
719 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700720
721 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
722 mCurrentFrame.fbCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800723 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
724 mCurrentFrame.fbCount);
725}
726
Saurabh Shahaa236822013-04-24 18:07:26 -0700727bool MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800728 if(!allocLayerPipes(ctx, list)) {
729 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700730 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800731 }
732
Saurabh Shahaa236822013-04-24 18:07:26 -0700733 bool fbBatch = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800734 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700735 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800736 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800737 int mdpIndex = mCurrentFrame.layerToMDP[index];
738 hwc_layer_1_t* layer = &list->hwLayers[index];
739
740 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
741 cur_pipe->zOrder = mdpNextZOrder++;
742
743 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
744 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
745 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -0700746 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800747 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700748 } else if(fbBatch == false) {
749 mdpNextZOrder++;
750 fbBatch = true;
751 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800752 }
753
Saurabh Shahaa236822013-04-24 18:07:26 -0700754 return true;
755}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800756
Saurabh Shahaa236822013-04-24 18:07:26 -0700757bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
758 if(!allocLayerPipes(ctx, list)) {
759 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
760 return false;
761 }
762 //If we are in this block, it means we have yuv + rgb layers both
763 int mdpIdx = 0;
764 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
765 if(!mCurrentFrame.isFBComposed[index]) {
766 hwc_layer_1_t* layer = &list->hwLayers[index];
767 int mdpIndex = mCurrentFrame.layerToMDP[index];
768 MdpPipeInfo* cur_pipe =
769 mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
770 cur_pipe->zOrder = mdpIdx++;
771
772 if(configure(ctx, layer,
773 mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
774 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
775 layer %d",__FUNCTION__, index);
776 return false;
777 }
778 }
779 }
780 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800781}
782
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700783uint32_t MDPComp::calcMDPBytesRead(hwc_context_t *ctx,
784 hwc_display_contents_1_t* list) {
785 uint32_t size = 0;
786
Terence Hampson9cd5fa92013-09-10 17:06:37 -0400787 if(!qdutils::MDPVersion::getInstance().is8x74v2())
788 return 0;
789
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700790 for (uint32_t i = 0; i < list->numHwLayers - 1; i++) {
791 if(!mCurrentFrame.isFBComposed[i]) {
792 hwc_layer_1_t* layer = &list->hwLayers[i];
793 private_handle_t *hnd = (private_handle_t *)layer->handle;
Terence Hampson9cd5fa92013-09-10 17:06:37 -0400794 if (hnd) {
795 hwc_rect_t crop = layer->sourceCrop;
Saurabh Shah90789162013-09-16 10:29:20 -0700796 hwc_rect_t dst = layer->displayFrame;
797 trimLayer(ctx, mDpy, layer->transform, crop, dst);
Terence Hampson9cd5fa92013-09-10 17:06:37 -0400798 float bpp = ((float)hnd->size) / (hnd->width * hnd->height);
Saurabh Shah90789162013-09-16 10:29:20 -0700799 size += bpp * (crop.right - crop.left) *
800 (crop.bottom - crop.top) *
801 ctx->dpyAttr[mDpy].yres / (dst.bottom - dst.top);
Terence Hampson9cd5fa92013-09-10 17:06:37 -0400802 }
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700803 }
804 }
805
806 if(mCurrentFrame.fbCount) {
807 hwc_layer_1_t* layer = &list->hwLayers[list->numHwLayers - 1];
808 private_handle_t *hnd = (private_handle_t *)layer->handle;
Terence Hampson9cd5fa92013-09-10 17:06:37 -0400809 if (hnd)
810 size += hnd->size;
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700811 }
812
813 return size;
814}
815
816bool MDPComp::bandwidthCheck(hwc_context_t *ctx, const uint32_t& size) {
817 //Will be added for other targets if we run into bandwidth issues and when
818 //we have profiling data to set an upper limit.
819 if(qdutils::MDPVersion::getInstance().is8x74v2()) {
820 const uint32_t ONE_GIG = 1024 * 1024 * 1024;
821 double panelRefRate =
822 1000000000.0 / ctx->dpyAttr[mDpy].vsync_period;
823 if((size + sCompBytesClaimed) > ((sMaxBw / panelRefRate) * ONE_GIG)) {
824 return false;
825 }
826 }
827 return true;
828}
829
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800830int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700831 int ret = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700832 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -0700833
Saurabh Shahb39f8152013-08-22 10:21:44 -0700834 //reset old data
835 mCurrentFrame.reset(numLayers);
Prabhanjan Kandula088bd892013-07-02 23:47:13 +0530836
Saurabh Shahb39f8152013-08-22 10:21:44 -0700837 //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU
838 //do not cache the information for next draw cycle.
839 if(numLayers > MAX_NUM_APP_LAYERS) {
Prabhanjan Kandula25469a52013-07-12 16:19:31 +0530840 mCachedFrame.updateCounts(mCurrentFrame);
Tatenda Chipeperekwa835337a2013-09-27 16:58:43 -0700841 ALOGE("%s: Number of App layers exceeded the limit ",
842 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700843 ret = -1;
Tatenda Chipeperekwa835337a2013-09-27 16:58:43 -0700844 return ret;
Saurabh Shahb39f8152013-08-22 10:21:44 -0700845 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800846
Saurabh Shahb39f8152013-08-22 10:21:44 -0700847 //Hard conditions, if not met, cannot do MDP comp
848 if(!isFrameDoable(ctx)) {
849 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
850 __FUNCTION__);
851 reset(numLayers, list);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700852 ret = -1;
853 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -0700854 }
855
856 //Check whether layers marked for MDP Composition is actually doable.
857 if(isFullFrameDoable(ctx, list)) {
858 mCurrentFrame.map();
859 //Configure framebuffer first if applicable
860 if(mCurrentFrame.fbZ >= 0) {
861 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list,
862 mCurrentFrame.fbZ)) {
863 ALOGE("%s configure framebuffer failed", __func__);
864 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -0700865 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700866 ret = -1;
867 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -0700868 }
869 }
870 //Acquire and Program MDP pipes
871 if(!programMDP(ctx, list)) {
872 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -0700873 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700874 ret = -1;
875 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -0700876 } else { //Success
877 //Any change in composition types needs an FB refresh
878 mCurrentFrame.needsRedraw = false;
879 if(mCurrentFrame.fbCount &&
880 ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700881 (mCurrentFrame.fbCount != mCachedFrame.fbCount) ||
Saurabh Shahb39f8152013-08-22 10:21:44 -0700882 (mCurrentFrame.fbZ != mCachedFrame.fbZ) ||
883 (!mCurrentFrame.mdpCount) ||
884 (list->flags & HWC_GEOMETRY_CHANGED) ||
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700885 isSkipPresent(ctx, mDpy))) {
Saurabh Shahb39f8152013-08-22 10:21:44 -0700886 mCurrentFrame.needsRedraw = true;
887 }
888 }
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700889 } else if(isOnlyVideoDoable(ctx, list, false /*secure only*/) ||
890 isOnlyVideoDoable(ctx, list, true /*secure only*/)) {
Saurabh Shahb39f8152013-08-22 10:21:44 -0700891 //All layers marked for MDP comp cannot be bypassed.
892 //Try to compose atleast YUV layers through MDP comp and let
893 //all the RGB layers compose in FB
894 //Destination over
895 mCurrentFrame.fbZ = -1;
896 if(mCurrentFrame.fbCount)
897 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
898
899 mCurrentFrame.map();
900
901 //Configure framebuffer first if applicable
902 if(mCurrentFrame.fbZ >= 0) {
903 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, mCurrentFrame.fbZ)) {
904 ALOGE("%s configure framebuffer failed", __func__);
905 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -0700906 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700907 ret = -1;
908 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -0700909 }
910 }
911 if(!programYUV(ctx, list)) {
912 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -0700913 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700914 ret = -1;
915 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -0700916 }
917 } else {
918 reset(numLayers, list);
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700919 ret = -1;
920 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -0700921 }
922
923 //UpdateLayerFlags
924 setMDPCompLayerFlags(ctx, list);
925 mCachedFrame.updateCounts(mCurrentFrame);
926
Prabhanjan Kandula25469a52013-07-12 16:19:31 +0530927 // unlock it before calling dump function to avoid deadlock
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800928 if(isDebug()) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700929 ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800930 android::String8 sDump("");
931 dump(sDump);
932 ALOGE("%s",sDump.string());
933 }
934
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700935exit:
936 sCompBytesClaimed += calcMDPBytesRead(ctx, list);
937 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800938}
939
Saurabh Shah88e4d272013-09-03 13:31:29 -0700940//=============MDPCompNonSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800941
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700942/*
943 * Configures pipe(s) for MDP composition
944 */
Saurabh Shah88e4d272013-09-03 13:31:29 -0700945int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800946 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -0700947 MdpPipeInfoNonSplit& mdp_info =
948 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -0800949 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
950 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
951 eIsFg isFg = IS_FG_OFF;
952 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700953
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800954 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
955 __FUNCTION__, layer, zOrder, dest);
956
Saurabh Shah88e4d272013-09-03 13:31:29 -0700957 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800958 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700959}
960
Saurabh Shah88e4d272013-09-03 13:31:29 -0700961bool MDPCompNonSplit::arePipesAvailable(hwc_context_t *ctx,
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700962 hwc_display_contents_1_t* list) {
963 overlay::Overlay& ov = *ctx->mOverlay;
964 int numPipesNeeded = mCurrentFrame.mdpCount;
965 int availPipes = ov.availablePipes(mDpy, Overlay::MIXER_DEFAULT);
966
967 //Reserve pipe for FB
968 if(mCurrentFrame.fbCount)
969 availPipes -= 1;
970
971 if(numPipesNeeded > availPipes) {
972 ALOGD_IF(isDebug(), "%s: Insufficient pipes, dpy %d needed %d, avail %d",
973 __FUNCTION__, mDpy, numPipesNeeded, availPipes);
974 return false;
975 }
976
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700977 if(not areVGPipesAvailable(ctx, list)) {
978 return false;
979 }
980
981 return true;
982}
983
984bool MDPCompNonSplit::areVGPipesAvailable(hwc_context_t *ctx,
985 hwc_display_contents_1_t* list) {
986 overlay::Overlay& ov = *ctx->mOverlay;
987 int pipesNeeded = 0;
988 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
989 if(!mCurrentFrame.isFBComposed[i]) {
990 hwc_layer_1_t* layer = &list->hwLayers[i];
991 hwc_rect_t dst = layer->displayFrame;
992 private_handle_t *hnd = (private_handle_t *)layer->handle;
993 if(isYuvBuffer(hnd)) {
994 pipesNeeded++;
995 }
996 }
997 }
998
999 int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
1000 if(pipesNeeded > availableVGPipes) {
1001 ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
1002 "dpy %d needed %d, avail %d",
1003 __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
1004 return false;
1005 }
1006
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001007 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001008}
1009
Saurabh Shah88e4d272013-09-03 13:31:29 -07001010bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001011 hwc_display_contents_1_t* list) {
1012 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001013
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001014 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001015
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001016 hwc_layer_1_t* layer = &list->hwLayers[index];
1017 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001018 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001019 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001020 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001021 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001022 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001023 ePipeType type = MDPCOMP_OV_ANY;
1024
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001025 if(isYuvBuffer(hnd)) {
1026 type = MDPCOMP_OV_VG;
Saurabh Shah8a117932013-05-23 12:48:13 -07001027 } else if(!qhwc::needsScaling(ctx, layer, mDpy)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001028 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
1029 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001030 type = MDPCOMP_OV_DMA;
1031 }
1032
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001033 pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001034 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001035 ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
1036 __FUNCTION__, (int) type);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001037 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001038 }
1039 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001040 return true;
1041}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001042
Saurabh Shah88e4d272013-09-03 13:31:29 -07001043bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001044
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001045 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001046 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1047 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -08001048 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001049
1050 if(!ctx || !list) {
1051 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001052 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001053 }
1054
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301055 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
1056 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
1057 return true;
1058 }
1059
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001060 /* reset Invalidator */
Saurabh Shah2d998a92013-05-14 17:55:58 -07001061 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001062 idleInvalidator->markForSleep();
1063
1064 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001065 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001066
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001067 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1068 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001069 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001070 if(mCurrentFrame.isFBComposed[i]) continue;
1071
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001072 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001073 private_handle_t *hnd = (private_handle_t *)layer->handle;
1074 if(!hnd) {
1075 ALOGE("%s handle null", __FUNCTION__);
1076 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001077 }
1078
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001079 int mdpIndex = mCurrentFrame.layerToMDP[i];
1080
Saurabh Shah88e4d272013-09-03 13:31:29 -07001081 MdpPipeInfoNonSplit& pipe_info =
1082 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001083 ovutils::eDest dest = pipe_info.index;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001084 if(dest == ovutils::OV_INVALID) {
1085 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001086 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001087 }
1088
Saurabh Shahacf10202013-02-26 10:15:15 -08001089 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1090 continue;
1091 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001092
Saurabh Shahacf10202013-02-26 10:15:15 -08001093 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001094 using pipe: %d", __FUNCTION__, layer,
1095 hnd, dest );
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001096
Saurabh Shahacf10202013-02-26 10:15:15 -08001097 int fd = hnd->fd;
1098 uint32_t offset = hnd->offset;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07001099
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001100 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shahacf10202013-02-26 10:15:15 -08001101 if(rot) {
1102 if(!rot->queueBuffer(fd, offset))
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001103 return false;
Saurabh Shahacf10202013-02-26 10:15:15 -08001104 fd = rot->getDstMemId();
1105 offset = rot->getDstOffset();
1106 }
1107
1108 if (!ov.queueBuffer(fd, offset, dest)) {
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301109 ALOGE("%s: queueBuffer failed for display:%d ", __FUNCTION__, mDpy);
Saurabh Shahacf10202013-02-26 10:15:15 -08001110 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001111 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001112
1113 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001114 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001115 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001116}
1117
Saurabh Shah88e4d272013-09-03 13:31:29 -07001118//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001119
Saurabh Shah88e4d272013-09-03 13:31:29 -07001120int MDPCompSplit::pipesNeeded(hwc_context_t *ctx,
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001121 hwc_display_contents_1_t* list,
1122 int mixer) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001123 int pipesNeeded = 0;
Saurabh Shah67a38c32013-06-10 16:23:15 -07001124 const int xres = ctx->dpyAttr[mDpy].xres;
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001125
1126 const int lSplit = getLeftSplit(ctx, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001127
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001128 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1129 if(!mCurrentFrame.isFBComposed[i]) {
1130 hwc_layer_1_t* layer = &list->hwLayers[i];
1131 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001132 if(mixer == Overlay::MIXER_LEFT && dst.left < lSplit) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001133 pipesNeeded++;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001134 } else if(mixer == Overlay::MIXER_RIGHT && dst.right > lSplit) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001135 pipesNeeded++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001136 }
1137 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001138 }
1139 return pipesNeeded;
1140}
1141
Saurabh Shah88e4d272013-09-03 13:31:29 -07001142bool MDPCompSplit::arePipesAvailable(hwc_context_t *ctx,
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001143 hwc_display_contents_1_t* list) {
1144 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shah082468e2013-09-12 10:05:32 -07001145 int totalPipesNeeded = 0;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001146
1147 for(int i = 0; i < Overlay::MIXER_MAX; i++) {
1148 int numPipesNeeded = pipesNeeded(ctx, list, i);
1149 int availPipes = ov.availablePipes(mDpy, i);
1150
1151 //Reserve pipe(s)for FB
1152 if(mCurrentFrame.fbCount)
Saurabh Shah082468e2013-09-12 10:05:32 -07001153 numPipesNeeded += 1;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001154
Saurabh Shah082468e2013-09-12 10:05:32 -07001155 totalPipesNeeded += numPipesNeeded;
1156
1157 //Per mixer check.
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001158 if(numPipesNeeded > availPipes) {
1159 ALOGD_IF(isDebug(), "%s: Insufficient pipes for "
1160 "dpy %d mixer %d needed %d, avail %d",
1161 __FUNCTION__, mDpy, i, numPipesNeeded, availPipes);
1162 return false;
1163 }
1164 }
Saurabh Shah082468e2013-09-12 10:05:32 -07001165
1166 //Per display check, since unused pipes can get counted twice.
1167 int totalPipesAvailable = ov.availablePipes(mDpy);
1168 if(totalPipesNeeded > totalPipesAvailable) {
1169 ALOGD_IF(isDebug(), "%s: Insufficient pipes for "
1170 "dpy %d needed %d, avail %d",
1171 __FUNCTION__, mDpy, totalPipesNeeded, totalPipesAvailable);
1172 return false;
1173 }
1174
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001175 if(not areVGPipesAvailable(ctx, list)) {
1176 return false;
1177 }
1178
1179 return true;
1180}
1181
1182bool MDPCompSplit::areVGPipesAvailable(hwc_context_t *ctx,
1183 hwc_display_contents_1_t* list) {
1184 overlay::Overlay& ov = *ctx->mOverlay;
1185 int pipesNeeded = 0;
1186 const int lSplit = getLeftSplit(ctx, mDpy);
1187 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1188 if(!mCurrentFrame.isFBComposed[i]) {
1189 hwc_layer_1_t* layer = &list->hwLayers[i];
1190 hwc_rect_t dst = layer->displayFrame;
1191 private_handle_t *hnd = (private_handle_t *)layer->handle;
1192 if(isYuvBuffer(hnd)) {
1193 if(dst.left < lSplit) {
1194 pipesNeeded++;
1195 }
1196 if(dst.right > lSplit) {
1197 pipesNeeded++;
1198 }
1199 }
1200 }
1201 }
1202
1203 int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
1204 if(pipesNeeded > availableVGPipes) {
1205 ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
1206 "dpy %d needed %d, avail %d",
1207 __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
1208 return false;
1209 }
1210
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001211 return true;
1212}
1213
Saurabh Shah88e4d272013-09-03 13:31:29 -07001214bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
1215 MdpPipeInfoSplit& pipe_info,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001216 ePipeType type) {
1217 const int xres = ctx->dpyAttr[mDpy].xres;
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001218 const int lSplit = getLeftSplit(ctx, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001219
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001220 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001221 pipe_info.lIndex = ovutils::OV_INVALID;
1222 pipe_info.rIndex = ovutils::OV_INVALID;
1223
1224 if (dst.left < lSplit) {
1225 pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_LEFT);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001226 if(pipe_info.lIndex == ovutils::OV_INVALID)
1227 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001228 }
1229
1230 if(dst.right > lSplit) {
1231 pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_RIGHT);
1232 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001233 return false;
1234 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001235
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001236 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001237}
1238
Saurabh Shah88e4d272013-09-03 13:31:29 -07001239bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001240 hwc_display_contents_1_t* list) {
1241 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001242
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001243 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001244
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001245 hwc_layer_1_t* layer = &list->hwLayers[index];
1246 private_handle_t *hnd = (private_handle_t *)layer->handle;
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001247 int mdpIndex = mCurrentFrame.layerToMDP[index];
1248 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001249 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001250 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001251 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001252 ePipeType type = MDPCOMP_OV_ANY;
1253
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001254 if(isYuvBuffer(hnd)) {
1255 type = MDPCOMP_OV_VG;
Sushil Chauhan15a2ea62013-09-04 18:28:36 -07001256 } else if(!qhwc::needsScalingWithSplit(ctx, layer, mDpy)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001257 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001258 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001259 type = MDPCOMP_OV_DMA;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001260 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001261
1262 if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001263 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
1264 __FUNCTION__, (int) type);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001265 return false;
1266 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001267 }
1268 return true;
1269}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001270
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001271/*
1272 * Configures pipe(s) for MDP composition
1273 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001274int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001275 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001276 MdpPipeInfoSplit& mdp_info =
1277 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001278 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1279 eIsFg isFg = IS_FG_OFF;
1280 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1281 eDest lDest = mdp_info.lIndex;
1282 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001283
1284 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
1285 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
1286
Saurabh Shah88e4d272013-09-03 13:31:29 -07001287 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001288 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001289}
1290
Saurabh Shah88e4d272013-09-03 13:31:29 -07001291bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001292
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001293 if(!isEnabled()) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001294 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1295 return true;
1296 }
1297
1298 if(!ctx || !list) {
1299 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001300 return false;
1301 }
1302
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301303 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
1304 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
1305 return true;
1306 }
1307
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001308 /* reset Invalidator */
Saurabh Shah2d998a92013-05-14 17:55:58 -07001309 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001310 idleInvalidator->markForSleep();
1311
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001312 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001313 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001314
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001315 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1316 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001317 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001318 if(mCurrentFrame.isFBComposed[i]) continue;
1319
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001320 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001321 private_handle_t *hnd = (private_handle_t *)layer->handle;
1322 if(!hnd) {
1323 ALOGE("%s handle null", __FUNCTION__);
1324 return false;
1325 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001326
1327 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1328 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001329 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001330
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001331 int mdpIndex = mCurrentFrame.layerToMDP[i];
1332
Saurabh Shah88e4d272013-09-03 13:31:29 -07001333 MdpPipeInfoSplit& pipe_info =
1334 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001335 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shahacf10202013-02-26 10:15:15 -08001336
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001337 ovutils::eDest indexL = pipe_info.lIndex;
1338 ovutils::eDest indexR = pipe_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001339
Saurabh Shahacf10202013-02-26 10:15:15 -08001340 int fd = hnd->fd;
1341 int offset = hnd->offset;
1342
Saurabh Shaha9da08f2013-07-03 13:27:53 -07001343 if(ctx->mAD->isModeOn()) {
1344 if(ctx->mAD->draw(ctx, fd, offset)) {
1345 fd = ctx->mAD->getDstFd(ctx);
1346 offset = ctx->mAD->getDstOffset(ctx);
1347 }
1348 }
1349
Saurabh Shahacf10202013-02-26 10:15:15 -08001350 if(rot) {
1351 rot->queueBuffer(fd, offset);
1352 fd = rot->getDstMemId();
1353 offset = rot->getDstOffset();
1354 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001355
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001356 //************* play left mixer **********
1357 if(indexL != ovutils::OV_INVALID) {
1358 ovutils::eDest destL = (ovutils::eDest)indexL;
Saurabh Shahacf10202013-02-26 10:15:15 -08001359 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001360 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
Saurabh Shahacf10202013-02-26 10:15:15 -08001361 if (!ov.queueBuffer(fd, offset, destL)) {
1362 ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__);
1363 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001364 }
1365 }
1366
1367 //************* play right mixer **********
1368 if(indexR != ovutils::OV_INVALID) {
1369 ovutils::eDest destR = (ovutils::eDest)indexR;
Saurabh Shahacf10202013-02-26 10:15:15 -08001370 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001371 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
Saurabh Shahacf10202013-02-26 10:15:15 -08001372 if (!ov.queueBuffer(fd, offset, destR)) {
1373 ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__);
1374 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001375 }
1376 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001377
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001378 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1379 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001380
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001381 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001382}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001383}; //namespace
1384