blob: c71b00bf7e9f37b57d1d7ccdb750e1479b09f44c [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 Sankaran6a9bb9e2013-08-01 14:19:26 -070044bool MDPComp::sEnablePartialFrameUpdate = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080045int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah8c5c8522013-08-29 17:32:49 -070046float MDPComp::sMaxBw = 2.3f;
47uint32_t MDPComp::sCompBytesClaimed = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070048
Saurabh Shah88e4d272013-09-03 13:31:29 -070049MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
50 if(isDisplaySplit(ctx, dpy)) {
51 return new MDPCompSplit(dpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080052 }
Saurabh Shah88e4d272013-09-03 13:31:29 -070053 return new MDPCompNonSplit(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080054}
55
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080056MDPComp::MDPComp(int dpy):mDpy(dpy){};
57
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080058void MDPComp::dump(android::String8& buf)
59{
Jeykumar Sankaran3c6bb042013-08-15 14:01:04 -070060 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
61 return;
62
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080063 dumpsys_log(buf,"HWC Map for Dpy: %s \n",
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070064 (mDpy == 0) ? "\"PRIMARY\"" :
65 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
Saurabh Shahe9bc60f2013-08-29 12:58:06 -070066 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
67 "fbCount:%2d \n", mCurrentFrame.layerCount,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080068 mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
69 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
70 (mCurrentFrame.needsRedraw? "YES" : "NO"),
71 mCurrentFrame.mdpCount, sMaxPipesPerMixer);
72 dumpsys_log(buf," --------------------------------------------- \n");
73 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
74 dumpsys_log(buf," --------------------------------------------- \n");
75 for(int index = 0; index < mCurrentFrame.layerCount; index++ )
76 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
77 index,
78 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070079 mCurrentFrame.layerToMDP[index],
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080080 (mCurrentFrame.isFBComposed[index] ?
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -070081 (mCurrentFrame.drop[index] ? "DROP" :
82 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080083 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
84 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
85 dumpsys_log(buf,"\n");
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080086}
87
88bool MDPComp::init(hwc_context_t *ctx) {
89
90 if(!ctx) {
91 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
92 return false;
93 }
94
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080095 char property[PROPERTY_VALUE_MAX];
96
97 sEnabled = false;
98 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -080099 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
100 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800101 sEnabled = true;
102 }
103
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700104 sEnableMixedMode = true;
105 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
106 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
107 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
108 sEnableMixedMode = false;
109 }
110
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800111 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
112 if(atoi(property) != 0)
113 sDebugLogs = true;
114 }
115
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700116 if(property_get("persist.hwc.partialupdate.enable", property, NULL) > 0) {
117 if((atoi(property) != 0) && ctx->mMDP.panel == MIPI_CMD_PANEL &&
118 qdutils::MDPVersion::getInstance().is8x74v2())
119 sEnablePartialFrameUpdate = true;
120 }
121 ALOGE_IF(isDebug(), "%s: Partial Update applicable?: %d",__FUNCTION__,
122 sEnablePartialFrameUpdate);
123
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800124 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
Saurabh Shah85234ec2013-04-12 17:09:00 -0700125 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
126 int val = atoi(property);
127 if(val >= 0)
128 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800129 }
130
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700131 if(property_get("debug.mdpcomp.bw", property, "0") > 0) {
132 float val = atof(property);
133 if(val > 0.0f) {
134 sMaxBw = val;
135 }
136 }
137
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400138 if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
139 // Idle invalidation is not necessary on command mode panels
140 long idle_timeout = DEFAULT_IDLE_TIME;
141 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
142 if(atoi(property) != 0)
143 idle_timeout = atoi(property);
144 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800145
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400146 //create Idle Invalidator only when not disabled through property
147 if(idle_timeout != -1)
148 idleInvalidator = IdleInvalidator::getInstance();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800149
Naseer Ahmedf40f2c82013-08-14 16:42:40 -0400150 if(idleInvalidator == NULL) {
151 ALOGE("%s: failed to instantiate idleInvalidator object",
152 __FUNCTION__);
153 } else {
154 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
155 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800156 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700157 return true;
158}
159
Saurabh Shah2a4eb1b2013-07-22 16:33:23 -0700160void MDPComp::reset(const int& numLayers, hwc_display_contents_1_t* list) {
161 mCurrentFrame.reset(numLayers);
162 mCachedFrame.cacheAll(list);
163 mCachedFrame.updateCounts(mCurrentFrame);
164}
165
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700166void MDPComp::timeout_handler(void *udata) {
167 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
168
169 if(!ctx) {
170 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
171 return;
172 }
173
Jesse Hall3be78d92012-08-21 15:12:23 -0700174 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700175 ALOGE("%s: HWC proc not registered", __FUNCTION__);
176 return;
177 }
178 sIdleFallBack = true;
179 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700180 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700181}
182
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800183void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800184 hwc_display_contents_1_t* list) {
185 LayerProp *layerProp = ctx->layerProp[mDpy];
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800186
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800187 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800188 hwc_layer_1_t* layer = &(list->hwLayers[index]);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800189 if(!mCurrentFrame.isFBComposed[index]) {
190 layerProp[index].mFlags |= HWC_MDPCOMP;
191 layer->compositionType = HWC_OVERLAY;
192 layer->hints |= HWC_HINT_CLEAR_FB;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800193 } else {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700194 /* Drop the layer when its already present in FB OR when it lies
195 * outside frame's ROI */
196 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800197 layer->compositionType = HWC_OVERLAY;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700198 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800199 }
200 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700201}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500202
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800203MDPComp::FrameInfo::FrameInfo() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700204 reset(0);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800205}
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800206
Saurabh Shahaa236822013-04-24 18:07:26 -0700207void MDPComp::FrameInfo::reset(const int& numLayers) {
208 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800209 if(mdpToLayer[i].pipeInfo) {
210 delete mdpToLayer[i].pipeInfo;
211 mdpToLayer[i].pipeInfo = NULL;
212 //We dont own the rotator
213 mdpToLayer[i].rot = NULL;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800214 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800215 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800216
217 memset(&mdpToLayer, 0, sizeof(mdpToLayer));
218 memset(&layerToMDP, -1, sizeof(layerToMDP));
Saurabh Shahaa236822013-04-24 18:07:26 -0700219 memset(&isFBComposed, 1, sizeof(isFBComposed));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800220
Saurabh Shahaa236822013-04-24 18:07:26 -0700221 layerCount = numLayers;
222 fbCount = numLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800223 mdpCount = 0;
Saurabh Shah2f3895f2013-05-02 10:13:31 -0700224 needsRedraw = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800225 fbZ = 0;
226}
227
Saurabh Shahaa236822013-04-24 18:07:26 -0700228void MDPComp::FrameInfo::map() {
229 // populate layer and MDP maps
230 int mdpIdx = 0;
231 for(int idx = 0; idx < layerCount; idx++) {
232 if(!isFBComposed[idx]) {
233 mdpToLayer[mdpIdx].listIndex = idx;
234 layerToMDP[idx] = mdpIdx++;
235 }
236 }
237}
238
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800239MDPComp::LayerCache::LayerCache() {
240 reset();
241}
242
243void MDPComp::LayerCache::reset() {
Saurabh Shahaa236822013-04-24 18:07:26 -0700244 memset(&hnd, 0, sizeof(hnd));
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530245 memset(&isFBComposed, true, sizeof(isFBComposed));
246 memset(&drop, false, sizeof(drop));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800247 layerCount = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -0700248}
249
250void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
251 const int numAppLayers = list->numHwLayers - 1;
252 for(int i = 0; i < numAppLayers; i++) {
253 hnd[i] = list->hwLayers[i].handle;
254 }
255}
256
257void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700258 layerCount = curFrame.layerCount;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +0530259 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
260 memcpy(&drop, &curFrame.drop, sizeof(drop));
261}
262
263bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame) {
264 if(layerCount != curFrame.layerCount)
265 return false;
266 for(int i = 0; i < curFrame.layerCount; i++) {
267 if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
268 (curFrame.drop[i] != drop[i])) {
269 return false;
270 }
271 }
272 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800273}
274
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700275bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
276 private_handle_t *hnd = (private_handle_t *)layer->handle;
277 if((not isYuvBuffer(hnd) and has90Transform(layer)) or
278 (not isValidDimension(ctx,layer))
279 //More conditions here, SKIP, sRGB+Blend etc
280 ) {
281 return false;
282 }
283 return true;
284}
285
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530286bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
Saurabh Shah4fdde762013-04-30 18:47:33 -0700287 const int dpy = HWC_DISPLAY_PRIMARY;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800288 private_handle_t *hnd = (private_handle_t *)layer->handle;
289
290 if(!hnd) {
291 ALOGE("%s: layer handle is NULL", __FUNCTION__);
292 return false;
293 }
294
Naseer Ahmede850a802013-09-06 13:12:52 -0400295 //XXX: Investigate doing this with pixel phase on MDSS
Naseer Ahmede77f8082013-10-10 13:42:48 -0400296 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
Naseer Ahmede850a802013-09-06 13:12:52 -0400297 return false;
298
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800299 int hw_w = ctx->dpyAttr[mDpy].xres;
300 int hw_h = ctx->dpyAttr[mDpy].yres;
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800301
Saurabh Shah62e1d732013-09-17 10:44:05 -0700302 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700303 hwc_rect_t dst = layer->displayFrame;
Saurabh Shah4fdde762013-04-30 18:47:33 -0700304 int crop_w = crop.right - crop.left;
305 int crop_h = crop.bottom - crop.top;
306 int dst_w = dst.right - dst.left;
307 int dst_h = dst.bottom - dst.top;
308 float w_dscale = ceilf((float)crop_w / (float)dst_w);
309 float h_dscale = ceilf((float)crop_h / (float)dst_h);
310
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800311 /* Workaround for MDP HW limitation in DSI command mode panels where
312 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
313 * less than 5 pixels
Sravan Kumar D.V.Nad5d9292013-04-24 14:23:04 +0530314 * There also is a HW limilation in MDP, minimum block size is 2x2
315 * Fallback to GPU if height is less than 2.
316 */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800317 if((crop_w < 5)||(crop_h < 5))
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800318 return false;
319
Saurabh Shah4fdde762013-04-30 18:47:33 -0700320 const uint32_t downscale =
321 qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
322 if(ctx->mMDP.version >= qdutils::MDSS_V5) {
323 /* Workaround for downscales larger than 4x.
324 * Will be removed once decimator block is enabled for MDSS
325 */
326 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
327 if(crop_w > MAX_DISPLAY_DIM || w_dscale > downscale ||
328 h_dscale > downscale)
329 return false;
330 } else {
331 if(w_dscale > 64 || h_dscale > 64)
332 return false;
333 }
334 } else { //A-family
335 if(w_dscale > downscale || h_dscale > downscale)
336 return false;
337 }
338
Jeykumar Sankaranc18dbc22013-02-08 14:29:44 -0800339 return true;
340}
341
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700342ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type,
343 int mixer) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800344 overlay::Overlay& ov = *ctx->mOverlay;
345 ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
346
347 switch(type) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800348 case MDPCOMP_OV_DMA:
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700349 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy, mixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800350 if(mdp_pipe != ovutils::OV_INVALID) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800351 return mdp_pipe;
352 }
353 case MDPCOMP_OV_ANY:
354 case MDPCOMP_OV_RGB:
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700355 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy, mixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800356 if(mdp_pipe != ovutils::OV_INVALID) {
357 return mdp_pipe;
358 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800359
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800360 if(type == MDPCOMP_OV_RGB) {
361 //Requested only for RGB pipe
362 break;
363 }
364 case MDPCOMP_OV_VG:
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700365 return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy, mixer);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800366 default:
367 ALOGE("%s: Invalid pipe type",__FUNCTION__);
368 return ovutils::OV_INVALID;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800369 };
370 return ovutils::OV_INVALID;
371}
372
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800373bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700374 bool ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700375 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800376
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800377 if(!isEnabled()) {
378 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700379 ret = false;
Saurabh Shahd4e65852013-06-17 11:33:53 -0700380 } else if(qdutils::MDPVersion::getInstance().is8x26() &&
Jeykumar Sankaran27dee262013-08-01 17:09:54 -0700381 ctx->mVideoTransFlag && ctx->mVirtualDisplay->isConnected()) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700382 //1 Padding round to shift pipes across mixers
383 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
384 __FUNCTION__);
385 ret = false;
Jeykumar Sankaran27dee262013-08-01 17:09:54 -0700386 } else if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isConfiguring ||
387 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isConfiguring) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800388 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800389 __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700390 ret = false;
Saurabh Shahaa236822013-04-24 18:07:26 -0700391 } else if(ctx->isPaddingRound) {
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700392 ctx->isPaddingRound = false;
393 ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -0700394 ret = false;
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700395 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700396 return ret;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800397}
398
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800399/*
400 * 1) Identify layers that are not visible in the updating ROI and drop them
401 * from composition.
402 * 2) If we have a scaling layers which needs cropping against generated ROI.
403 * Reset ROI to full resolution.
404 */
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700405bool MDPComp::validateAndApplyROI(hwc_context_t *ctx,
406 hwc_display_contents_1_t* list, hwc_rect_t roi) {
407 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
408
409 if(!isValidRect(roi))
410 return false;
411
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800412 hwc_rect_t visibleRect = roi;
413
414 for(int i = numAppLayers - 1; i >= 0; i--){
415
416 if(!isValidRect(visibleRect)) {
417 mCurrentFrame.drop[i] = true;
418 mCurrentFrame.dropCount++;
419 }
420
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700421 const hwc_layer_1_t* layer = &list->hwLayers[i];
422
423 hwc_rect_t dstRect = layer->displayFrame;
Arun Kumar K.R91090c72013-10-28 19:40:18 -0700424 hwc_rect_t srcRect = integerizeSourceCrop(layer->sourceCropf);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700425 int transform = layer->transform;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700426
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800427 hwc_rect_t res = getIntersection(visibleRect, dstRect);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700428
429 int res_w = res.right - res.left;
430 int res_h = res.bottom - res.top;
431 int dst_w = dstRect.right - dstRect.left;
432 int dst_h = dstRect.bottom - dstRect.top;
433
434 if(!isValidRect(res)) {
435 mCurrentFrame.drop[i] = true;
436 mCurrentFrame.dropCount++;
437 }else {
438 /* Reset frame ROI when any layer which needs scaling also needs ROI
439 * cropping */
440 if((res_w != dst_w || res_h != dst_h) &&
441 needsScaling (ctx, layer, mDpy)) {
Arpita Banerjeed8965982013-11-08 17:27:33 -0800442 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700443 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
444 mCurrentFrame.dropCount = 0;
445 return false;
446 }
447 }
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800448
449 if (layer->blending == HWC_BLENDING_NONE)
450 visibleRect = deductRect(visibleRect, res);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700451 }
452 return true;
453}
454
455void MDPComp::generateROI(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
456 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
457
458 if(!sEnablePartialFrameUpdate) {
459 return;
460 }
461
462 if(mDpy || isDisplaySplit(ctx, mDpy)){
463 ALOGE_IF(isDebug(), "%s: ROI not supported for"
464 "the (1) external / virtual display's (2) dual DSI displays",
465 __FUNCTION__);
466 return;
467 }
468
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -0800469 if(isSkipPresent(ctx, mDpy))
470 return;
471
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700472 if(list->flags & HWC_GEOMETRY_CHANGED)
473 return;
474
475 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
476 for(int index = 0; index < numAppLayers; index++ ) {
477 if ((mCachedFrame.hnd[index] != list->hwLayers[index].handle) ||
478 isYuvBuffer((private_handle_t *)list->hwLayers[index].handle)) {
479 hwc_rect_t dstRect = list->hwLayers[index].displayFrame;
Arun Kumar K.R91090c72013-10-28 19:40:18 -0700480 hwc_rect_t srcRect = integerizeSourceCrop(
481 list->hwLayers[index].sourceCropf);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700482 int transform = list->hwLayers[index].transform;
483
484 /* Intersect against display boundaries */
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700485 roi = getUnion(roi, dstRect);
486 }
487 }
488
489 if(!validateAndApplyROI(ctx, list, roi)){
490 roi = (struct hwc_rect) {0, 0,
491 (int)ctx->dpyAttr[mDpy].xres, (int)ctx->dpyAttr[mDpy].yres};
492 }
493
494 ctx->listStats[mDpy].roi.x = roi.left;
495 ctx->listStats[mDpy].roi.y = roi.top;
496 ctx->listStats[mDpy].roi.w = roi.right - roi.left;
497 ctx->listStats[mDpy].roi.h = roi.bottom - roi.top;
498
499 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
500 roi.left, roi.top, roi.right, roi.bottom);
501}
502
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800503/* Checks for conditions where all the layers marked for MDP comp cannot be
504 * bypassed. On such conditions we try to bypass atleast YUV layers */
505bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
506 hwc_display_contents_1_t* list){
507
Saurabh Shahaa236822013-04-24 18:07:26 -0700508 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800509
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700510 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) {
Saurabh Shah2d998a92013-05-14 17:55:58 -0700511 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
512 return false;
513 }
514
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800515 if(isSkipPresent(ctx, mDpy)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700516 ALOGD_IF(isDebug(),"%s: SKIP present: %d",
517 __FUNCTION__,
518 isSkipPresent(ctx, mDpy));
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800519 return false;
520 }
521
Saurabh Shah9f084ad2013-05-02 11:28:09 -0700522 if(ctx->listStats[mDpy].needsAlphaScale
523 && ctx->mMDP.version < qdutils::MDSS_V5) {
524 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
525 return false;
526 }
527
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800528 for(int i = 0; i < numAppLayers; ++i) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800529 hwc_layer_1_t* layer = &list->hwLayers[i];
530 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -0800531
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700532 if(isYuvBuffer(hnd) && has90Transform(layer)) {
533 if(!canUseRotator(ctx, mDpy)) {
534 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
535 __FUNCTION__, mDpy);
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700536 return false;
537 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800538 }
Prabhanjan Kandula9fb032a2013-06-18 17:37:22 +0530539
540 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
541 // may not need it if Gfx pre-rotation can handle all flips & rotations
542 if(qdutils::MDPVersion::getInstance().is8x26() &&
543 (ctx->dpyAttr[mDpy].xres > 1024) &&
544 (layer->transform & HWC_TRANSFORM_FLIP_H) &&
545 (!isYuvBuffer(hnd)))
546 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800547 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700548
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700549 if(ctx->mAD->isDoable()) {
550 return false;
551 }
552
Saurabh Shahaa236822013-04-24 18:07:26 -0700553 //If all above hard conditions are met we can do full or partial MDP comp.
554 bool ret = false;
555 if(fullMDPComp(ctx, list)) {
556 ret = true;
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700557 } else if(partialMDPComp(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700558 ret = true;
559 }
560 return ret;
561}
562
563bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700564 //Will benefit presentation / secondary-only layer.
565 if((mDpy > HWC_DISPLAY_PRIMARY) &&
566 (list->numHwLayers - 1) > MAX_SEC_LAYERS) {
567 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
568 return false;
569 }
570
571 const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
572 for(int i = 0; i < numAppLayers; i++) {
573 hwc_layer_1_t* layer = &list->hwLayers[i];
574 if(not isSupportedForMDPComp(ctx, layer)) {
575 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
576 return false;
577 }
578 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700579 mCurrentFrame.fbCount = 0;
580 mCurrentFrame.fbZ = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700581 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
582 sizeof(mCurrentFrame.isFBComposed));
583 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
584 mCurrentFrame.dropCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700585
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700586 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700587 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
588 return false;
589 }
590
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700591 if(!arePipesAvailable(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700592 return false;
593 }
594
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700595 uint32_t size = calcMDPBytesRead(ctx, list);
596 if(!bandwidthCheck(ctx, size)) {
597 ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
598 return false;
599 }
600
Saurabh Shahaa236822013-04-24 18:07:26 -0700601 return true;
602}
603
604bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
605{
Jeykumar Sankaran24c199d2013-05-24 09:40:36 -0700606 if(!sEnableMixedMode) {
607 //Mixed mode is disabled. No need to even try caching.
608 return false;
609 }
610
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700611 bool ret = false;
612 if(isLoadBasedCompDoable(ctx, list)) {
613 ret = loadBasedComp(ctx, list);
614 }
615
616 if(!ret) {
617 ret = cacheBasedComp(ctx, list);
618 }
619
620 return ret;
621}
622
623bool MDPComp::cacheBasedComp(hwc_context_t *ctx,
624 hwc_display_contents_1_t* list) {
625 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahaa236822013-04-24 18:07:26 -0700626 mCurrentFrame.reset(numAppLayers);
627 updateLayerCache(ctx, list);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700628
629 //If an MDP marked layer is unsupported cannot do partial MDP Comp
630 for(int i = 0; i < numAppLayers; i++) {
631 if(!mCurrentFrame.isFBComposed[i]) {
632 hwc_layer_1_t* layer = &list->hwLayers[i];
633 if(not isSupportedForMDPComp(ctx, layer)) {
634 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
635 __FUNCTION__);
636 return false;
637 }
638 }
639 }
640
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700641 updateYUV(ctx, list, false /*secure only*/);
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530642 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700643 if(!ret) {
644 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
645 return false;
646 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700647
648 int mdpCount = mCurrentFrame.mdpCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700649
650 //Will benefit cases where a video has non-updating background.
651 if((mDpy > HWC_DISPLAY_PRIMARY) and
652 (mdpCount > MAX_SEC_LAYERS)) {
653 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
654 return false;
655 }
656
Saurabh Shahaa236822013-04-24 18:07:26 -0700657 if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used
658 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
659 return false;
660 }
661
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700662 if(!arePipesAvailable(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700663 return false;
664 }
665
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700666 uint32_t size = calcMDPBytesRead(ctx, list);
667 if(!bandwidthCheck(ctx, size)) {
668 ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
669 return false;
670 }
671
Saurabh Shahaa236822013-04-24 18:07:26 -0700672 return true;
673}
674
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700675bool MDPComp::loadBasedComp(hwc_context_t *ctx,
676 hwc_display_contents_1_t* list) {
677 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
678 mCurrentFrame.reset(numAppLayers);
679
680 //TODO BatchSize could be optimized further based on available pipes, split
681 //displays etc.
682 const int batchSize = numAppLayers - (sMaxPipesPerMixer - 1);
683 if(batchSize <= 0) {
684 ALOGD_IF(isDebug(), "%s: Not attempting", __FUNCTION__);
685 return false;
686 }
687
688 int minBatchStart = -1;
689 size_t minBatchPixelCount = SIZE_MAX;
690
691 for(int i = 0; i <= numAppLayers - batchSize; i++) {
692 uint32_t batchPixelCount = 0;
693 for(int j = i; j < i + batchSize; j++) {
694 hwc_layer_1_t* layer = &list->hwLayers[j];
Arun Kumar K.R91090c72013-10-28 19:40:18 -0700695 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700696 batchPixelCount += (crop.right - crop.left) *
697 (crop.bottom - crop.top);
698 }
699
700 if(batchPixelCount < minBatchPixelCount) {
701 minBatchPixelCount = batchPixelCount;
702 minBatchStart = i;
703 }
704 }
705
706 if(minBatchStart < 0) {
707 ALOGD_IF(isDebug(), "%s: No batch found batchSize %d numAppLayers %d",
708 __FUNCTION__, batchSize, numAppLayers);
709 return false;
710 }
711
712 for(int i = 0; i < numAppLayers; i++) {
713 if(i < minBatchStart || i >= minBatchStart + batchSize) {
714 hwc_layer_1_t* layer = &list->hwLayers[i];
715 if(not isSupportedForMDPComp(ctx, layer)) {
716 ALOGD_IF(isDebug(), "%s: MDP unsupported layer found at %d",
717 __FUNCTION__, i);
718 return false;
719 }
720 mCurrentFrame.isFBComposed[i] = false;
721 }
722 }
723
724 mCurrentFrame.fbZ = minBatchStart;
725 mCurrentFrame.fbCount = batchSize;
726 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - batchSize;
727
728 if(!arePipesAvailable(ctx, list)) {
729 return false;
730 }
731
732 ALOGD_IF(isDebug(), "%s: fbZ %d batchSize %d",
733 __FUNCTION__, mCurrentFrame.fbZ, batchSize);
734 return true;
735}
736
737bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx,
738 hwc_display_contents_1_t* list) {
739 if(mDpy or isSecurePresent(ctx, mDpy) or
740 not (list->flags & HWC_GEOMETRY_CHANGED)) {
741 return false;
742 }
743 return true;
744}
745
Saurabh Shahaa236822013-04-24 18:07:26 -0700746bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx,
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700747 hwc_display_contents_1_t* list, bool secureOnly) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700748 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700749
Saurabh Shahaa236822013-04-24 18:07:26 -0700750 mCurrentFrame.reset(numAppLayers);
Saurabh Shah90b7b9b2013-09-12 16:36:08 -0700751 updateYUV(ctx, list, secureOnly);
Saurabh Shah4fdde762013-04-30 18:47:33 -0700752 int mdpCount = mCurrentFrame.mdpCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700753 int fbNeeded = (mCurrentFrame.fbCount != 0);
Saurabh Shahaa236822013-04-24 18:07:26 -0700754
755 if(!isYuvPresent(ctx, mDpy)) {
756 return false;
757 }
758
Jeykumar Sankaranf42f0d82013-11-08 18:09:20 -0800759 /* Bail out if we are processing only secured video layers
760 * and we dont have any */
761 if(!isSecurePresent(ctx, mDpy) && secureOnly){
762 return false;
763 }
764
Saurabh Shah4fdde762013-04-30 18:47:33 -0700765 if(!mdpCount)
766 return false;
767
Saurabh Shahaa236822013-04-24 18:07:26 -0700768 if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
769 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
770 return false;
771 }
772
Saurabh Shahaf5f5972013-07-30 13:56:35 -0700773 if(!arePipesAvailable(ctx, list)) {
Saurabh Shahaa236822013-04-24 18:07:26 -0700774 return false;
775 }
776
Saurabh Shah8c5c8522013-08-29 17:32:49 -0700777 uint32_t size = calcMDPBytesRead(ctx, list);
778 if(!bandwidthCheck(ctx, size)) {
779 ALOGD_IF(isDebug(), "%s: Exceeds bandwidth",__FUNCTION__);
780 return false;
781 }
782
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800783 return true;
784}
785
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800786/* Checks for conditions where YUV layers cannot be bypassed */
787bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
Saurabh Shahe2474082013-05-15 16:32:13 -0700788 bool extAnimBlockFeature = mDpy && ctx->listStats[mDpy].isDisplayAnimating;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800789
Saurabh Shahe2474082013-05-15 16:32:13 -0700790 if(isSkipLayer(layer) && !extAnimBlockFeature) {
791 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800792 return false;
793 }
794
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700795 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) {
796 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
797 return false;
798 }
799
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800800 if(isSecuring(ctx, layer)) {
801 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
802 return false;
803 }
804
Saurabh Shah4fdde762013-04-30 18:47:33 -0700805 if(!isValidDimension(ctx, layer)) {
806 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
807 __FUNCTION__);
808 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800809 }
Saurabh Shah4fdde762013-04-30 18:47:33 -0700810
Naseer Ahmeddc61a972013-07-10 17:50:54 -0400811 if(layer->planeAlpha < 0xFF) {
812 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
813 in video only mode",
814 __FUNCTION__);
815 return false;
816 }
817
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800818 return true;
819}
820
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530821/* starts at fromIndex and check for each layer to find
822 * if it it has overlapping with any Updating layer above it in zorder
823 * till the end of the batch. returns true if it finds any intersection */
824bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
825 int fromIndex, int toIndex) {
826 for(int i = fromIndex; i < toIndex; i++) {
827 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
828 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
829 return false;
830 }
831 }
832 }
833 return true;
834}
835
836/* Checks if given layer at targetLayerIndex has any
837 * intersection with all the updating layers in beween
838 * fromIndex and toIndex. Returns true if it finds intersectiion */
839bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
840 int fromIndex, int toIndex, int targetLayerIndex) {
841 for(int i = fromIndex; i <= toIndex; i++) {
842 if(!mCurrentFrame.isFBComposed[i]) {
843 if(areLayersIntersecting(&list->hwLayers[i],
844 &list->hwLayers[targetLayerIndex])) {
845 return true;
846 }
847 }
848 }
849 return false;
850}
851
852int MDPComp::getBatch(hwc_display_contents_1_t* list,
853 int& maxBatchStart, int& maxBatchEnd,
854 int& maxBatchCount) {
855 int i = 0;
856 int updatingLayersAbove = 0;//Updating layer count in middle of batch
857 int fbZOrder =-1;
858 while (i < mCurrentFrame.layerCount) {
859 int batchCount = 0;
860 int batchStart = i;
861 int batchEnd = i;
862 int fbZ = batchStart;
863 int firstZReverseIndex = -1;
864 while(i < mCurrentFrame.layerCount) {
865 if(!mCurrentFrame.isFBComposed[i]) {
866 if(!batchCount) {
867 i++;
868 break;
869 }
870 updatingLayersAbove++;
871 i++;
872 continue;
873 } else {
874 if(mCurrentFrame.drop[i]) {
875 i++;
876 continue;
877 } else if(updatingLayersAbove <= 0) {
878 batchCount++;
879 batchEnd = i;
880 i++;
881 continue;
882 } else { //Layer is FBComposed, not a drop & updatingLayer > 0
883
884 // We have a valid updating layer already. If layer-i not
885 // have overlapping with all updating layers in between
886 // batch-start and i, then we can add layer i to batch.
887 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
888 batchCount++;
889 batchEnd = i;
890 i++;
891 continue;
892 } else if(canPushBatchToTop(list, batchStart, i)) {
893 //If All the non-updating layers with in this batch
894 //does not have intersection with the updating layers
895 //above in z-order, then we can safely move the batch to
896 //higher z-order. Increment fbZ as it is moving up.
897 if( firstZReverseIndex < 0) {
898 firstZReverseIndex = i;
899 }
900 batchCount++;
901 batchEnd = i;
902 fbZ += updatingLayersAbove;
903 i++;
904 updatingLayersAbove = 0;
905 continue;
906 } else {
907 //both failed.start the loop again from here.
908 if(firstZReverseIndex >= 0) {
909 i = firstZReverseIndex;
910 }
911 break;
912 }
913 }
914 }
915 }
916 if(batchCount > maxBatchCount) {
917 maxBatchCount = batchCount;
918 maxBatchStart = batchStart;
919 maxBatchEnd = batchEnd;
920 fbZOrder = fbZ;
921 }
922 }
923 return fbZOrder;
924}
925
926bool MDPComp::markLayersForCaching(hwc_context_t* ctx,
927 hwc_display_contents_1_t* list) {
928 /* Idea is to keep as many non-updating(cached) layers in FB and
929 * send rest of them through MDP. This is done in 2 steps.
930 * 1. Find the maximum contiguous batch of non-updating layers.
931 * 2. See if we can improve this batch size for caching by adding
932 * opaque layers around the batch, if they don't have
933 * any overlapping with the updating layers in between.
934 * NEVER mark an updating layer for caching.
935 * But cached ones can be marked for MDP */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800936
937 int maxBatchStart = -1;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700938 int maxBatchEnd = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800939 int maxBatchCount = 0;
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530940 int fbZ = -1;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800941
942 /* All or Nothing is cached. No batching needed */
Saurabh Shahaa236822013-04-24 18:07:26 -0700943 if(!mCurrentFrame.fbCount) {
944 mCurrentFrame.fbZ = -1;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700945 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -0700946 }
947 if(!mCurrentFrame.mdpCount) {
948 mCurrentFrame.fbZ = 0;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700949 return true;
Saurabh Shahaa236822013-04-24 18:07:26 -0700950 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800951
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530952 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800953
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530954 /* reset rest of the layers lying inside ROI for MDP comp */
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800955 for(int i = 0; i < mCurrentFrame.layerCount; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700956 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700957 if((i < maxBatchStart || i > maxBatchEnd) &&
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530958 mCurrentFrame.isFBComposed[i]){
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700959 if(!mCurrentFrame.drop[i]){
960 //If an unsupported layer is being attempted to
961 //be pulled out we should fail
962 if(not isSupportedForMDPComp(ctx, layer)) {
963 return false;
964 }
965 mCurrentFrame.isFBComposed[i] = false;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700966 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800967 }
968 }
969
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530970 // update the frame data
971 mCurrentFrame.fbZ = fbZ;
972 mCurrentFrame.fbCount = maxBatchCount;
Saurabh Shahaa236822013-04-24 18:07:26 -0700973 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700974 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800975
976 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +0530977 mCurrentFrame.fbCount);
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700978
979 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800980}
Saurabh Shah85234ec2013-04-12 17:09:00 -0700981
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800982void MDPComp::updateLayerCache(hwc_context_t* ctx,
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700983 hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800984 int numAppLayers = ctx->listStats[mDpy].numAppLayers;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700985 int fbCount = 0;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800986
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800987 for(int i = 0; i < numAppLayers; i++) {
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700988 hwc_layer_1_t* layer = &list->hwLayers[i];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800989 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700990 if(!mCurrentFrame.drop[i])
991 fbCount++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800992 mCurrentFrame.isFBComposed[i] = true;
993 } else {
Saurabh Shahaa236822013-04-24 18:07:26 -0700994 mCurrentFrame.isFBComposed[i] = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800995 mCachedFrame.hnd[i] = list->hwLayers[i].handle;
996 }
997 }
Saurabh Shahaa236822013-04-24 18:07:26 -0700998
Saurabh Shahe9bc60f2013-08-29 12:58:06 -0700999 mCurrentFrame.fbCount = fbCount;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001000 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount
1001 - mCurrentFrame.dropCount;
Saurabh Shahe9bc60f2013-08-29 12:58:06 -07001002
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001003 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d"
1004 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount,
1005 mCurrentFrame.dropCount);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001006}
1007
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001008void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1009 bool secureOnly) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001010 int nYuvCount = ctx->listStats[mDpy].yuvCount;
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001011 if(!nYuvCount && mDpy) {
1012 //Reset "No animation on external display" related parameters.
1013 ctx->mPrevCropVideo.left = ctx->mPrevCropVideo.top =
1014 ctx->mPrevCropVideo.right = ctx->mPrevCropVideo.bottom = 0;
1015 ctx->mPrevDestVideo.left = ctx->mPrevDestVideo.top =
1016 ctx->mPrevDestVideo.right = ctx->mPrevDestVideo.bottom = 0;
1017 ctx->mPrevTransformVideo = 0;
1018 return;
1019 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001020 for(int index = 0;index < nYuvCount; index++){
1021 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1022 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1023
1024 if(!isYUVDoable(ctx, layer)) {
1025 if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
1026 mCurrentFrame.isFBComposed[nYuvIndex] = true;
1027 mCurrentFrame.fbCount++;
1028 }
1029 } else {
1030 if(mCurrentFrame.isFBComposed[nYuvIndex]) {
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001031 private_handle_t *hnd = (private_handle_t *)layer->handle;
1032 if(!secureOnly || isSecureBuffer(hnd)) {
1033 mCurrentFrame.isFBComposed[nYuvIndex] = false;
1034 mCurrentFrame.fbCount--;
1035 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001036 }
1037 }
1038 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001039
1040 mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001041 mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1042 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001043 mCurrentFrame.fbCount);
1044}
1045
Saurabh Shahaa236822013-04-24 18:07:26 -07001046bool MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001047 if(!allocLayerPipes(ctx, list)) {
1048 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
Saurabh Shahaa236822013-04-24 18:07:26 -07001049 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001050 }
1051
1052 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
Saurabh Shahaa236822013-04-24 18:07:26 -07001053 index++) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001054 if(!mCurrentFrame.isFBComposed[index]) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001055 int mdpIndex = mCurrentFrame.layerToMDP[index];
1056 hwc_layer_1_t* layer = &list->hwLayers[index];
1057
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301058 //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1059 if(mdpNextZOrder == mCurrentFrame.fbZ) {
1060 mdpNextZOrder++;
1061 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001062 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1063 cur_pipe->zOrder = mdpNextZOrder++;
1064
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301065
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001066 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1067 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
1068 layer %d",__FUNCTION__, index);
Saurabh Shahaa236822013-04-24 18:07:26 -07001069 return false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001070 }
Saurabh Shahaa236822013-04-24 18:07:26 -07001071 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001072 }
1073
Saurabh Shahaa236822013-04-24 18:07:26 -07001074 return true;
1075}
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001076
Saurabh Shahaa236822013-04-24 18:07:26 -07001077bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1078 if(!allocLayerPipes(ctx, list)) {
1079 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
1080 return false;
1081 }
1082 //If we are in this block, it means we have yuv + rgb layers both
1083 int mdpIdx = 0;
1084 for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1085 if(!mCurrentFrame.isFBComposed[index]) {
1086 hwc_layer_1_t* layer = &list->hwLayers[index];
1087 int mdpIndex = mCurrentFrame.layerToMDP[index];
1088 MdpPipeInfo* cur_pipe =
1089 mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1090 cur_pipe->zOrder = mdpIdx++;
1091
1092 if(configure(ctx, layer,
1093 mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1094 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
1095 layer %d",__FUNCTION__, index);
1096 return false;
1097 }
1098 }
1099 }
1100 return true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001101}
1102
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001103uint32_t MDPComp::calcMDPBytesRead(hwc_context_t *ctx,
1104 hwc_display_contents_1_t* list) {
1105 uint32_t size = 0;
1106
Terence Hampson9cd5fa92013-09-10 17:06:37 -04001107 if(!qdutils::MDPVersion::getInstance().is8x74v2())
1108 return 0;
1109
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001110 for (uint32_t i = 0; i < list->numHwLayers - 1; i++) {
1111 if(!mCurrentFrame.isFBComposed[i]) {
1112 hwc_layer_1_t* layer = &list->hwLayers[i];
1113 private_handle_t *hnd = (private_handle_t *)layer->handle;
Terence Hampson9cd5fa92013-09-10 17:06:37 -04001114 if (hnd) {
Saurabh Shah62e1d732013-09-17 10:44:05 -07001115 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shah90789162013-09-16 10:29:20 -07001116 hwc_rect_t dst = layer->displayFrame;
Terence Hampson9cd5fa92013-09-10 17:06:37 -04001117 float bpp = ((float)hnd->size) / (hnd->width * hnd->height);
Saurabh Shah90789162013-09-16 10:29:20 -07001118 size += bpp * (crop.right - crop.left) *
1119 (crop.bottom - crop.top) *
1120 ctx->dpyAttr[mDpy].yres / (dst.bottom - dst.top);
Terence Hampson9cd5fa92013-09-10 17:06:37 -04001121 }
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001122 }
1123 }
1124
1125 if(mCurrentFrame.fbCount) {
1126 hwc_layer_1_t* layer = &list->hwLayers[list->numHwLayers - 1];
1127 private_handle_t *hnd = (private_handle_t *)layer->handle;
Terence Hampson9cd5fa92013-09-10 17:06:37 -04001128 if (hnd)
1129 size += hnd->size;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001130 }
1131
1132 return size;
1133}
1134
1135bool MDPComp::bandwidthCheck(hwc_context_t *ctx, const uint32_t& size) {
1136 //Will be added for other targets if we run into bandwidth issues and when
1137 //we have profiling data to set an upper limit.
1138 if(qdutils::MDPVersion::getInstance().is8x74v2()) {
1139 const uint32_t ONE_GIG = 1024 * 1024 * 1024;
1140 double panelRefRate =
1141 1000000000.0 / ctx->dpyAttr[mDpy].vsync_period;
1142 if((size + sCompBytesClaimed) > ((sMaxBw / panelRefRate) * ONE_GIG)) {
1143 return false;
1144 }
1145 }
1146 return true;
1147}
1148
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001149int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001150 int ret = 0;
Saurabh Shahaa236822013-04-24 18:07:26 -07001151 const int numLayers = ctx->listStats[mDpy].numAppLayers;
Ramkumar Radhakrishnanc5893f12013-06-06 19:43:53 -07001152
Saurabh Shahb39f8152013-08-22 10:21:44 -07001153 //reset old data
1154 mCurrentFrame.reset(numLayers);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001155 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1156 mCurrentFrame.dropCount = 0;
Prabhanjan Kandula088bd892013-07-02 23:47:13 +05301157
Saurabh Shahb39f8152013-08-22 10:21:44 -07001158 //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU
1159 //do not cache the information for next draw cycle.
1160 if(numLayers > MAX_NUM_APP_LAYERS) {
Prabhanjan Kandula25469a52013-07-12 16:19:31 +05301161 mCachedFrame.updateCounts(mCurrentFrame);
Arpita Banerjeed8965982013-11-08 17:27:33 -08001162 ALOGI("%s: Number of App layers exceeded the limit ",
Tatenda Chipeperekwa835337a2013-09-27 16:58:43 -07001163 __FUNCTION__);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001164 ret = -1;
Tatenda Chipeperekwa835337a2013-09-27 16:58:43 -07001165 return ret;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001166 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001167
Saurabh Shahb39f8152013-08-22 10:21:44 -07001168 //Hard conditions, if not met, cannot do MDP comp
1169 if(!isFrameDoable(ctx)) {
1170 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
1171 __FUNCTION__);
1172 reset(numLayers, list);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001173 ret = -1;
1174 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001175 }
1176
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001177 generateROI(ctx, list);
1178
Saurabh Shahb39f8152013-08-22 10:21:44 -07001179 //Check whether layers marked for MDP Composition is actually doable.
1180 if(isFullFrameDoable(ctx, list)) {
1181 mCurrentFrame.map();
1182 //Configure framebuffer first if applicable
1183 if(mCurrentFrame.fbZ >= 0) {
1184 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list,
1185 mCurrentFrame.fbZ)) {
1186 ALOGE("%s configure framebuffer failed", __func__);
1187 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -07001188 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001189 ret = -1;
1190 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001191 }
1192 }
1193 //Acquire and Program MDP pipes
1194 if(!programMDP(ctx, list)) {
1195 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -07001196 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001197 ret = -1;
1198 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001199 } else { //Success
1200 //Any change in composition types needs an FB refresh
1201 mCurrentFrame.needsRedraw = false;
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +05301202 if(!mCachedFrame.isSameFrame(mCurrentFrame) ||
Saurabh Shahb39f8152013-08-22 10:21:44 -07001203 (list->flags & HWC_GEOMETRY_CHANGED) ||
Prabhanjan Kandula2243aa62013-10-24 12:58:55 +05301204 isSkipPresent(ctx, mDpy)) {
Saurabh Shahb39f8152013-08-22 10:21:44 -07001205 mCurrentFrame.needsRedraw = true;
1206 }
1207 }
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001208 } else if(isOnlyVideoDoable(ctx, list, false /*secure only*/) ||
1209 isOnlyVideoDoable(ctx, list, true /*secure only*/)) {
Saurabh Shahb39f8152013-08-22 10:21:44 -07001210 //All layers marked for MDP comp cannot be bypassed.
1211 //Try to compose atleast YUV layers through MDP comp and let
1212 //all the RGB layers compose in FB
1213 //Destination over
1214 mCurrentFrame.fbZ = -1;
1215 if(mCurrentFrame.fbCount)
1216 mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
1217
1218 mCurrentFrame.map();
1219
1220 //Configure framebuffer first if applicable
1221 if(mCurrentFrame.fbZ >= 0) {
1222 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, mCurrentFrame.fbZ)) {
1223 ALOGE("%s configure framebuffer failed", __func__);
1224 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -07001225 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001226 ret = -1;
1227 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001228 }
1229 }
1230 if(!programYUV(ctx, list)) {
1231 reset(numLayers, list);
Saurabh Shah6be7c782013-08-28 15:13:52 -07001232 ctx->mOverlay->clear(mDpy);
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001233 ret = -1;
1234 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001235 }
1236 } else {
1237 reset(numLayers, list);
Jeykumar Sankaran862d87c2013-11-08 16:47:26 -08001238 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
1239 mCurrentFrame.dropCount = 0;
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001240 ret = -1;
1241 goto exit;
Saurabh Shahb39f8152013-08-22 10:21:44 -07001242 }
Saurabh Shahb39f8152013-08-22 10:21:44 -07001243 //UpdateLayerFlags
1244 setMDPCompLayerFlags(ctx, list);
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -07001245 mCachedFrame.cacheAll(list);
Saurabh Shahb39f8152013-08-22 10:21:44 -07001246 mCachedFrame.updateCounts(mCurrentFrame);
1247
Prabhanjan Kandula25469a52013-07-12 16:19:31 +05301248 // unlock it before calling dump function to avoid deadlock
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001249 if(isDebug()) {
Saurabh Shahaa236822013-04-24 18:07:26 -07001250 ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED));
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001251 android::String8 sDump("");
1252 dump(sDump);
1253 ALOGE("%s",sDump.string());
1254 }
1255
Saurabh Shah8c5c8522013-08-29 17:32:49 -07001256exit:
1257 sCompBytesClaimed += calcMDPBytesRead(ctx, list);
1258 return ret;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001259}
1260
Saurabh Shah88e4d272013-09-03 13:31:29 -07001261//=============MDPCompNonSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001262
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001263/*
1264 * Configures pipe(s) for MDP composition
1265 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001266int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001267 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001268 MdpPipeInfoNonSplit& mdp_info =
1269 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001270 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
1271 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1272 eIsFg isFg = IS_FG_OFF;
1273 eDest dest = mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001274
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001275 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
1276 __FUNCTION__, layer, zOrder, dest);
1277
Saurabh Shah88e4d272013-09-03 13:31:29 -07001278 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001279 &PipeLayerPair.rot);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001280}
1281
Saurabh Shah88e4d272013-09-03 13:31:29 -07001282bool MDPCompNonSplit::arePipesAvailable(hwc_context_t *ctx,
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001283 hwc_display_contents_1_t* list) {
1284 overlay::Overlay& ov = *ctx->mOverlay;
1285 int numPipesNeeded = mCurrentFrame.mdpCount;
1286 int availPipes = ov.availablePipes(mDpy, Overlay::MIXER_DEFAULT);
1287
1288 //Reserve pipe for FB
1289 if(mCurrentFrame.fbCount)
1290 availPipes -= 1;
1291
1292 if(numPipesNeeded > availPipes) {
1293 ALOGD_IF(isDebug(), "%s: Insufficient pipes, dpy %d needed %d, avail %d",
1294 __FUNCTION__, mDpy, numPipesNeeded, availPipes);
1295 return false;
1296 }
1297
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001298 if(not areVGPipesAvailable(ctx, list)) {
1299 return false;
1300 }
1301
1302 return true;
1303}
1304
1305bool MDPCompNonSplit::areVGPipesAvailable(hwc_context_t *ctx,
1306 hwc_display_contents_1_t* list) {
1307 overlay::Overlay& ov = *ctx->mOverlay;
1308 int pipesNeeded = 0;
1309 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1310 if(!mCurrentFrame.isFBComposed[i]) {
1311 hwc_layer_1_t* layer = &list->hwLayers[i];
1312 hwc_rect_t dst = layer->displayFrame;
1313 private_handle_t *hnd = (private_handle_t *)layer->handle;
1314 if(isYuvBuffer(hnd)) {
1315 pipesNeeded++;
1316 }
1317 }
1318 }
1319
1320 int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
1321 if(pipesNeeded > availableVGPipes) {
1322 ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
1323 "dpy %d needed %d, avail %d",
1324 __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
1325 return false;
1326 }
1327
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001328 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001329}
1330
Saurabh Shah88e4d272013-09-03 13:31:29 -07001331bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001332 hwc_display_contents_1_t* list) {
1333 for(int index = 0; index < mCurrentFrame.layerCount; index++) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001334
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001335 if(mCurrentFrame.isFBComposed[index]) continue;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001336
Jeykumar Sankarancf537002013-01-21 21:19:15 -08001337 hwc_layer_1_t* layer = &list->hwLayers[index];
1338 private_handle_t *hnd = (private_handle_t *)layer->handle;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001339 int mdpIndex = mCurrentFrame.layerToMDP[index];
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001340 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001341 info.pipeInfo = new MdpPipeInfoNonSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001342 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001343 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001344 ePipeType type = MDPCOMP_OV_ANY;
1345
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001346 if(isYuvBuffer(hnd)) {
1347 type = MDPCOMP_OV_VG;
Saurabh Shah8a117932013-05-23 12:48:13 -07001348 } else if(!qhwc::needsScaling(ctx, layer, mDpy)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001349 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
1350 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -08001351 type = MDPCOMP_OV_DMA;
1352 }
1353
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001354 pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001355 if(pipe_info.index == ovutils::OV_INVALID) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001356 ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
1357 __FUNCTION__, (int) type);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001358 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001359 }
1360 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001361 return true;
1362}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001363
Saurabh Shah88e4d272013-09-03 13:31:29 -07001364bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001365
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001366 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001367 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1368 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -08001369 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001370
1371 if(!ctx || !list) {
1372 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001373 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001374 }
1375
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301376 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
1377 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
1378 return true;
1379 }
1380
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001381 /* reset Invalidator */
Saurabh Shah2d998a92013-05-14 17:55:58 -07001382 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001383 idleInvalidator->markForSleep();
1384
1385 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001386 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001387
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001388 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1389 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001390 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001391 if(mCurrentFrame.isFBComposed[i]) continue;
1392
Naseer Ahmed5b6708a2012-08-02 13:46:08 -07001393 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001394 private_handle_t *hnd = (private_handle_t *)layer->handle;
1395 if(!hnd) {
1396 ALOGE("%s handle null", __FUNCTION__);
1397 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001398 }
1399
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001400 int mdpIndex = mCurrentFrame.layerToMDP[i];
1401
Saurabh Shah88e4d272013-09-03 13:31:29 -07001402 MdpPipeInfoNonSplit& pipe_info =
1403 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001404 ovutils::eDest dest = pipe_info.index;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001405 if(dest == ovutils::OV_INVALID) {
1406 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001407 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001408 }
1409
Saurabh Shahacf10202013-02-26 10:15:15 -08001410 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1411 continue;
1412 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001413
Saurabh Shahacf10202013-02-26 10:15:15 -08001414 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001415 using pipe: %d", __FUNCTION__, layer,
1416 hnd, dest );
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001417
Saurabh Shahacf10202013-02-26 10:15:15 -08001418 int fd = hnd->fd;
1419 uint32_t offset = hnd->offset;
Saurabh Shaha9da08f2013-07-03 13:27:53 -07001420
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001421 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shahacf10202013-02-26 10:15:15 -08001422 if(rot) {
1423 if(!rot->queueBuffer(fd, offset))
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001424 return false;
Saurabh Shahacf10202013-02-26 10:15:15 -08001425 fd = rot->getDstMemId();
1426 offset = rot->getDstOffset();
1427 }
1428
1429 if (!ov.queueBuffer(fd, offset, dest)) {
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301430 ALOGE("%s: queueBuffer failed for display:%d ", __FUNCTION__, mDpy);
Saurabh Shahacf10202013-02-26 10:15:15 -08001431 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001432 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001433
1434 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001435 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001436 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001437}
1438
Saurabh Shah88e4d272013-09-03 13:31:29 -07001439//=============MDPCompSplit===================================================
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001440
Saurabh Shah88e4d272013-09-03 13:31:29 -07001441int MDPCompSplit::pipesNeeded(hwc_context_t *ctx,
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001442 hwc_display_contents_1_t* list,
1443 int mixer) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001444 int pipesNeeded = 0;
Saurabh Shah67a38c32013-06-10 16:23:15 -07001445 const int xres = ctx->dpyAttr[mDpy].xres;
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001446
1447 const int lSplit = getLeftSplit(ctx, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001448
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001449 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1450 if(!mCurrentFrame.isFBComposed[i]) {
1451 hwc_layer_1_t* layer = &list->hwLayers[i];
1452 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001453 if(mixer == Overlay::MIXER_LEFT && dst.left < lSplit) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001454 pipesNeeded++;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001455 } else if(mixer == Overlay::MIXER_RIGHT && dst.right > lSplit) {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001456 pipesNeeded++;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001457 }
1458 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001459 }
1460 return pipesNeeded;
1461}
1462
Saurabh Shah88e4d272013-09-03 13:31:29 -07001463bool MDPCompSplit::arePipesAvailable(hwc_context_t *ctx,
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001464 hwc_display_contents_1_t* list) {
1465 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shah082468e2013-09-12 10:05:32 -07001466 int totalPipesNeeded = 0;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001467
1468 for(int i = 0; i < Overlay::MIXER_MAX; i++) {
1469 int numPipesNeeded = pipesNeeded(ctx, list, i);
1470 int availPipes = ov.availablePipes(mDpy, i);
1471
1472 //Reserve pipe(s)for FB
1473 if(mCurrentFrame.fbCount)
Saurabh Shah082468e2013-09-12 10:05:32 -07001474 numPipesNeeded += 1;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001475
Saurabh Shah082468e2013-09-12 10:05:32 -07001476 totalPipesNeeded += numPipesNeeded;
1477
1478 //Per mixer check.
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001479 if(numPipesNeeded > availPipes) {
1480 ALOGD_IF(isDebug(), "%s: Insufficient pipes for "
1481 "dpy %d mixer %d needed %d, avail %d",
1482 __FUNCTION__, mDpy, i, numPipesNeeded, availPipes);
1483 return false;
1484 }
1485 }
Saurabh Shah082468e2013-09-12 10:05:32 -07001486
1487 //Per display check, since unused pipes can get counted twice.
1488 int totalPipesAvailable = ov.availablePipes(mDpy);
1489 if(totalPipesNeeded > totalPipesAvailable) {
1490 ALOGD_IF(isDebug(), "%s: Insufficient pipes for "
1491 "dpy %d needed %d, avail %d",
1492 __FUNCTION__, mDpy, totalPipesNeeded, totalPipesAvailable);
1493 return false;
1494 }
1495
Saurabh Shah90b7b9b2013-09-12 16:36:08 -07001496 if(not areVGPipesAvailable(ctx, list)) {
1497 return false;
1498 }
1499
1500 return true;
1501}
1502
1503bool MDPCompSplit::areVGPipesAvailable(hwc_context_t *ctx,
1504 hwc_display_contents_1_t* list) {
1505 overlay::Overlay& ov = *ctx->mOverlay;
1506 int pipesNeeded = 0;
1507 const int lSplit = getLeftSplit(ctx, mDpy);
1508 for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1509 if(!mCurrentFrame.isFBComposed[i]) {
1510 hwc_layer_1_t* layer = &list->hwLayers[i];
1511 hwc_rect_t dst = layer->displayFrame;
1512 private_handle_t *hnd = (private_handle_t *)layer->handle;
1513 if(isYuvBuffer(hnd)) {
1514 if(dst.left < lSplit) {
1515 pipesNeeded++;
1516 }
1517 if(dst.right > lSplit) {
1518 pipesNeeded++;
1519 }
1520 }
1521 }
1522 }
1523
1524 int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
1525 if(pipesNeeded > availableVGPipes) {
1526 ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
1527 "dpy %d needed %d, avail %d",
1528 __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
1529 return false;
1530 }
1531
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001532 return true;
1533}
1534
Saurabh Shah88e4d272013-09-03 13:31:29 -07001535bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
1536 MdpPipeInfoSplit& pipe_info,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001537 ePipeType type) {
1538 const int xres = ctx->dpyAttr[mDpy].xres;
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001539 const int lSplit = getLeftSplit(ctx, mDpy);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001540
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001541 hwc_rect_t dst = layer->displayFrame;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001542 pipe_info.lIndex = ovutils::OV_INVALID;
1543 pipe_info.rIndex = ovutils::OV_INVALID;
1544
1545 if (dst.left < lSplit) {
1546 pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_LEFT);
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001547 if(pipe_info.lIndex == ovutils::OV_INVALID)
1548 return false;
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001549 }
1550
1551 if(dst.right > lSplit) {
1552 pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_RIGHT);
1553 if(pipe_info.rIndex == ovutils::OV_INVALID)
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001554 return false;
1555 }
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001556
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001557 return true;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001558}
1559
Saurabh Shah88e4d272013-09-03 13:31:29 -07001560bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001561 hwc_display_contents_1_t* list) {
1562 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001563
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001564 if(mCurrentFrame.isFBComposed[index]) continue;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001565
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001566 hwc_layer_1_t* layer = &list->hwLayers[index];
1567 private_handle_t *hnd = (private_handle_t *)layer->handle;
Saurabh Shah0d65dbe2013-06-06 18:33:16 -07001568 int mdpIndex = mCurrentFrame.layerToMDP[index];
1569 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
Saurabh Shah88e4d272013-09-03 13:31:29 -07001570 info.pipeInfo = new MdpPipeInfoSplit;
Saurabh Shah9e3adb22013-03-26 11:16:27 -07001571 info.rot = NULL;
Saurabh Shah88e4d272013-09-03 13:31:29 -07001572 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001573 ePipeType type = MDPCOMP_OV_ANY;
1574
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001575 if(isYuvBuffer(hnd)) {
1576 type = MDPCOMP_OV_VG;
Sushil Chauhan15a2ea62013-09-04 18:28:36 -07001577 } else if(!qhwc::needsScalingWithSplit(ctx, layer, mDpy)
Saurabh Shah85234ec2013-04-12 17:09:00 -07001578 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001579 && ctx->mMDP.version >= qdutils::MDSS_V5) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001580 type = MDPCOMP_OV_DMA;
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001581 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001582
1583 if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
Saurabh Shahe51f8ca2013-05-06 17:26:16 -07001584 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
1585 __FUNCTION__, (int) type);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001586 return false;
1587 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001588 }
1589 return true;
1590}
Saurabh Shahaf5f5972013-07-30 13:56:35 -07001591
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001592/*
1593 * Configures pipe(s) for MDP composition
1594 */
Saurabh Shah88e4d272013-09-03 13:31:29 -07001595int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
Saurabh Shah67a38c32013-06-10 16:23:15 -07001596 PipeLayerPair& PipeLayerPair) {
Saurabh Shah88e4d272013-09-03 13:31:29 -07001597 MdpPipeInfoSplit& mdp_info =
1598 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
Saurabh Shahacf10202013-02-26 10:15:15 -08001599 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1600 eIsFg isFg = IS_FG_OFF;
1601 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1602 eDest lDest = mdp_info.lIndex;
1603 eDest rDest = mdp_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001604
1605 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
1606 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
1607
Saurabh Shah88e4d272013-09-03 13:31:29 -07001608 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001609 rDest, &PipeLayerPair.rot);
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001610}
1611
Saurabh Shah88e4d272013-09-03 13:31:29 -07001612bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001613
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001614 if(!isEnabled()) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001615 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1616 return true;
1617 }
1618
1619 if(!ctx || !list) {
1620 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001621 return false;
1622 }
1623
Prabhanjan Kandula08222fc2013-07-10 17:20:59 +05301624 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) {
1625 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__);
1626 return true;
1627 }
1628
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001629 /* reset Invalidator */
Saurabh Shah2d998a92013-05-14 17:55:58 -07001630 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001631 idleInvalidator->markForSleep();
1632
Naseer Ahmed54821fe2012-11-28 18:44:38 -05001633 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001634 LayerProp *layerProp = ctx->layerProp[mDpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001635
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001636 int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1637 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001638 {
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001639 if(mCurrentFrame.isFBComposed[i]) continue;
1640
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001641 hwc_layer_1_t *layer = &list->hwLayers[i];
Saurabh Shahacf10202013-02-26 10:15:15 -08001642 private_handle_t *hnd = (private_handle_t *)layer->handle;
1643 if(!hnd) {
1644 ALOGE("%s handle null", __FUNCTION__);
1645 return false;
1646 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001647
1648 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1649 continue;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001650 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001651
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001652 int mdpIndex = mCurrentFrame.layerToMDP[i];
1653
Saurabh Shah88e4d272013-09-03 13:31:29 -07001654 MdpPipeInfoSplit& pipe_info =
1655 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001656 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
Saurabh Shahacf10202013-02-26 10:15:15 -08001657
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001658 ovutils::eDest indexL = pipe_info.lIndex;
1659 ovutils::eDest indexR = pipe_info.rIndex;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001660
Saurabh Shahacf10202013-02-26 10:15:15 -08001661 int fd = hnd->fd;
1662 int offset = hnd->offset;
1663
Saurabh Shaha9da08f2013-07-03 13:27:53 -07001664 if(ctx->mAD->isModeOn()) {
1665 if(ctx->mAD->draw(ctx, fd, offset)) {
1666 fd = ctx->mAD->getDstFd(ctx);
1667 offset = ctx->mAD->getDstOffset(ctx);
1668 }
1669 }
1670
Saurabh Shahacf10202013-02-26 10:15:15 -08001671 if(rot) {
1672 rot->queueBuffer(fd, offset);
1673 fd = rot->getDstMemId();
1674 offset = rot->getDstOffset();
1675 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001676
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001677 //************* play left mixer **********
1678 if(indexL != ovutils::OV_INVALID) {
1679 ovutils::eDest destL = (ovutils::eDest)indexL;
Saurabh Shahacf10202013-02-26 10:15:15 -08001680 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001681 using pipe: %d", __FUNCTION__, layer, hnd, indexL );
Saurabh Shahacf10202013-02-26 10:15:15 -08001682 if (!ov.queueBuffer(fd, offset, destL)) {
1683 ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__);
1684 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001685 }
1686 }
1687
1688 //************* play right mixer **********
1689 if(indexR != ovutils::OV_INVALID) {
1690 ovutils::eDest destR = (ovutils::eDest)indexR;
Saurabh Shahacf10202013-02-26 10:15:15 -08001691 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001692 using pipe: %d", __FUNCTION__, layer, hnd, indexR );
Saurabh Shahacf10202013-02-26 10:15:15 -08001693 if (!ov.queueBuffer(fd, offset, destR)) {
1694 ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__);
1695 return false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001696 }
1697 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001698
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001699 layerProp[i].mFlags &= ~HWC_MDPCOMP;
1700 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001701
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08001702 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001703}
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001704}; //namespace
1705