blob: 2e58b934c5906164a2a523c8af8bb9d2c6379b1f [file] [log] [blame]
Naseer Ahmed7c958d42012-07-31 18:57:03 -07001/*
Saurabh Shah56f610d2012-08-07 15:27:06 -07002 * Copyright (C) 2012, 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
19#include "hwc_mdpcomp.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050020#include <sys/ioctl.h>
Saurabh Shah56f610d2012-08-07 15:27:06 -070021#include "external.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080022#include "qdMetaData.h"
Naseer Ahmed7c958d42012-07-31 18:57:03 -070023
Naseer Ahmed7c958d42012-07-31 18:57:03 -070024namespace qhwc {
25
Naseer Ahmed54821fe2012-11-28 18:44:38 -050026namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070027
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080028//==============MDPComp========================================================
29
Naseer Ahmed7c958d42012-07-31 18:57:03 -070030IdleInvalidator *MDPComp::idleInvalidator = NULL;
31bool MDPComp::sIdleFallBack = false;
32bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050033bool MDPComp::sEnabled = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070034
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080035MDPComp* MDPComp::getObject(const int& width) {
36 //For now. Later check for width > 2048
37 return new MDPCompLowRes();
38}
39
40void MDPComp::dump(android::String8& buf)
41{
42 dumpsys_log(buf, " MDP Composition: ");
43 dumpsys_log(buf, "MDPCompState=%d\n", mState);
44 //XXX: Log more info
45}
46
47bool MDPComp::init(hwc_context_t *ctx) {
48
49 if(!ctx) {
50 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
51 return false;
52 }
53
54 if(!setupBasePipe(ctx)) {
55 ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
56 return false;
57 }
58
59 char property[PROPERTY_VALUE_MAX];
60
61 sEnabled = false;
62 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
63 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
64 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
65 sEnabled = true;
66 }
67
68 sDebugLogs = false;
69 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
70 if(atoi(property) != 0)
71 sDebugLogs = true;
72 }
73
74 unsigned long idle_timeout = DEFAULT_IDLE_TIME;
75 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
76 if(atoi(property) != 0)
77 idle_timeout = atoi(property);
78 }
79
80 //create Idle Invalidator
81 idleInvalidator = IdleInvalidator::getInstance();
82
83 if(idleInvalidator == NULL) {
84 ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
85 } else {
86 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
87 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -070088 return true;
89}
90
91void MDPComp::timeout_handler(void *udata) {
92 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
93
94 if(!ctx) {
95 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
96 return;
97 }
98
Jesse Hall3be78d92012-08-21 15:12:23 -070099 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700100 ALOGE("%s: HWC proc not registered", __FUNCTION__);
101 return;
102 }
103 sIdleFallBack = true;
104 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700105 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700106}
107
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800108void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
109 hwc_display_contents_1_t* list) {
110 const int dpy = HWC_DISPLAY_PRIMARY;
111 LayerProp *layerProp = ctx->layerProp[dpy];
112
113 for(int index = 0; index < ctx->listStats[dpy].numAppLayers; index++ ) {
114 hwc_layer_1_t* layer = &(list->hwLayers[index]);
115 layerProp[index].mFlags |= HWC_MDPCOMP;
116 layer->compositionType = HWC_OVERLAY;
117 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400118 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700119}
120
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800121void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
122 hwc_display_contents_1_t* list) {
123 const int dpy = HWC_DISPLAY_PRIMARY;
124 LayerProp *layerProp = ctx->layerProp[dpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700125
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800126 for (int index = 0 ;
127 index < ctx->listStats[dpy].numAppLayers; index++) {
128 if(layerProp[index].mFlags & HWC_MDPCOMP) {
129 layerProp[index].mFlags &= ~HWC_MDPCOMP;
130 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700131
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800132 if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
133 list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
134 }
135 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700136}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500137
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800138/*
139 * Sets up BORDERFILL as default base pipe and detaches RGB0.
140 * Framebuffer is always updated using PLAY ioctl.
141 */
142bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
143 const int dpy = HWC_DISPLAY_PRIMARY;
144 int fb_stride = ctx->dpyAttr[dpy].stride;
145 int fb_width = ctx->dpyAttr[dpy].xres;
146 int fb_height = ctx->dpyAttr[dpy].yres;
147 int fb_fd = ctx->dpyAttr[dpy].fd;
148
149 mdp_overlay ovInfo;
150 msmfb_overlay_data ovData;
151 memset(&ovInfo, 0, sizeof(mdp_overlay));
152 memset(&ovData, 0, sizeof(msmfb_overlay_data));
153
154 ovInfo.src.format = MDP_RGB_BORDERFILL;
155 ovInfo.src.width = fb_width;
156 ovInfo.src.height = fb_height;
157 ovInfo.src_rect.w = fb_width;
158 ovInfo.src_rect.h = fb_height;
159 ovInfo.dst_rect.w = fb_width;
160 ovInfo.dst_rect.h = fb_height;
161 ovInfo.id = MSMFB_NEW_REQUEST;
162
163 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
164 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
165 strerror(errno));
166 return false;
167 }
168
169 ovData.id = ovInfo.id;
170 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
171 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
172 strerror(errno));
173 return false;
174 }
175 return true;
176}
177
178void MDPComp::printInfo(hwc_layer_1_t* layer) {
179 hwc_rect_t sourceCrop = layer->sourceCrop;
180 hwc_rect_t displayFrame = layer->displayFrame;
181
182 int s_l = sourceCrop.left;
183 int s_t = sourceCrop.top;
184 int s_r = sourceCrop.right;
185 int s_b = sourceCrop.bottom;
186
187 int d_l = displayFrame.left;
188 int d_t = displayFrame.top;
189 int d_r = displayFrame.right;
190 int d_b = displayFrame.bottom;
191
192 ALOGD_IF(isDebug(), "src:[%d,%d,%d,%d] (%d x %d) \
193 dst:[%d,%d,%d,%d] (%d x %d)",
194 s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
195 d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
196}
197
198//=============MDPCompLowRes===================================================
199void MDPCompLowRes::reset(hwc_context_t *ctx,
200 hwc_display_contents_1_t* list ) {
201 //Reset flags and states
202 unsetMDPCompLayerFlags(ctx, list);
203 mCurrentFrame.count = 0;
204 if(mCurrentFrame.pipeLayer) {
205 free(mCurrentFrame.pipeLayer);
206 mCurrentFrame.pipeLayer = NULL;
207 }
208}
209
210void MDPCompLowRes::setVidInfo(hwc_layer_1_t *layer,
211 ovutils::eMdpFlags &mdpFlags) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500212 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800213 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500214
215 if(isSecureBuffer(hnd)) {
216 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500217 }
Ramkumar Radhakrishnan12b103b2013-01-09 17:47:56 -0800218 if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
219 metadata->interlaced) {
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800220 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
221 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500222}
223
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700224/*
225 * Configures pipe(s) for MDP composition
226 */
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800227int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
228 MdpPipeInfo& mdp_info) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700229 int nPipeIndex = mdp_info.index;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800230 const int dpy = HWC_DISPLAY_PRIMARY;
231 private_handle_t *hnd = (private_handle_t *)layer->handle;
232 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700233
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800234 if(!hnd) {
235 ALOGE("%s: layer handle is NULL", __FUNCTION__);
236 return -1;
237 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700238
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800239 int hw_w = ctx->dpyAttr[dpy].xres;
240 int hw_h = ctx->dpyAttr[dpy].yres;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700241
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800242 hwc_rect_t sourceCrop = layer->sourceCrop;
243 hwc_rect_t displayFrame = layer->displayFrame;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700244
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800245 const int src_w = sourceCrop.right - sourceCrop.left;
246 const int src_h = sourceCrop.bottom - sourceCrop.top;
247
248 hwc_rect_t crop = sourceCrop;
249 int crop_w = crop.right - crop.left;
250 int crop_h = crop.bottom - crop.top;
251
252 hwc_rect_t dst = displayFrame;
253 int dst_w = dst.right - dst.left;
254 int dst_h = dst.bottom - dst.top;
255
256 if(dst.left < 0 || dst.top < 0 ||
257 dst.right > hw_w || dst.bottom > hw_h) {
258 ALOGD_IF(isDebug(),"%s: Destination has negative coordinates",
259 __FUNCTION__);
260 qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, 0);
261
262 //Update calulated width and height
263 crop_w = crop.right - crop.left;
264 crop_h = crop.bottom - crop.top;
265
266 dst_w = dst.right - dst.left;
267 dst_h = dst.bottom - dst.top;
268 }
269
270 if( (dst_w > hw_w)|| (dst_h > hw_h)) {
271 ALOGD_IF(isDebug(),"%s: Dest rect exceeds FB", __FUNCTION__);
272 printInfo(layer);
273 dst_w = hw_w;
274 dst_h = hw_h;
275 }
276
277 // Determine pipe to set based on pipe index
278 ovutils::eDest dest = (ovutils::eDest)mdp_info.index;
279
280 ovutils::eZorder zOrder = ovutils::ZORDER_0;
281
282 if(mdp_info.zOrder == 0 ) {
283 zOrder = ovutils::ZORDER_0;
284 } else if(mdp_info.zOrder == 1 ) {
285 zOrder = ovutils::ZORDER_1;
286 } else if(mdp_info.zOrder == 2 ) {
287 zOrder = ovutils::ZORDER_2;
288 } else if(mdp_info.zOrder == 3) {
289 zOrder = ovutils::ZORDER_3;
290 }
291
292 // Order order order
293 // setSource - just setting source
294 // setParameter - changes src w/h/f accordingly
295 // setCrop - ROI - src_rect
296 // setPosition - dst_rect
297 // commit - commit changes to mdp driver
298 // queueBuffer - not here, happens when draw is called
299
300 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
301
302 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
303
304 if(isYuvBuffer(hnd))
305 setVidInfo(layer, mdpFlags);
306
307 ovutils::setMdpFlags(mdpFlags,ovutils::OV_MDP_BACKEND_COMPOSITION);
308
309 if(layer->blending == HWC_BLENDING_PREMULT) {
310 ovutils::setMdpFlags(mdpFlags,
311 ovutils::OV_MDP_BLEND_FG_PREMULT);
312 }
313
314 ovutils::eTransform orient = overlay::utils::OVERLAY_TRANSFORM_0 ;
315
316 if(!(layer->transform & HWC_TRANSFORM_ROT_90)) {
317 if(layer->transform & HWC_TRANSFORM_FLIP_H) {
318 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700319 }
320
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800321 if(layer->transform & HWC_TRANSFORM_FLIP_V) {
322 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700323 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800324 } else {
325 orient = static_cast<ovutils::eTransform>(layer->transform);
326 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700327
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800328 ovutils::PipeArgs parg(mdpFlags,
329 info,
330 zOrder,
331 ovutils::IS_FG_OFF,
332 ovutils::ROT_FLAG_DISABLED);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700333
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800334 ov.setSource(parg, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700335
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800336 ov.setTransform(orient, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700337
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800338 ovutils::Dim dcrop(crop.left, crop.top, crop_w, crop_h);
339 ov.setCrop(dcrop, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700340
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800341 ovutils::Dim dim(dst.left, dst.top, dst_w, dst_h);
342 ov.setPosition(dim, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700343
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800344 ALOGD_IF(isDebug(),"%s: MDP set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] \
345 nPipe: %d zorder: %d",__FUNCTION__, dcrop.x,
346 dcrop.y,dcrop.w, dcrop.h, dim.x, dim.y, dim.w, dim.h,
347 mdp_info.index, mdp_info.zOrder);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500348
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800349 if (!ov.commit(dest)) {
350 ALOGE("%s: commit failed", __FUNCTION__);
351 return -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700352 }
353 return 0;
354}
355
356/*
357 * MDPComp not possible when
358 * 1. We have more than sMaxLayers
359 * 2. External display connected
360 * 3. Composition is triggered by
361 * Idle timer expiry
362 * 4. Rotation is needed
363 * 5. Overlay in use
364 */
365
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800366bool MDPCompLowRes::isDoable(hwc_context_t *ctx,
367 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700368 //Number of layers
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800369 const int dpy = HWC_DISPLAY_PRIMARY;
370 int numAppLayers = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500371
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800372 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaranccb44602013-01-03 12:48:22 -0800373 int availablePipes = ov.availablePipes(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800374
375 if(numAppLayers < 1 || numAppLayers > (uint32_t)availablePipes) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700376 ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
377 return false;
378 }
379
Amara Venkata Mastan Manoj Kumar75526f52012-12-27 18:27:01 -0800380 if(ctx->mExtDispConfiguring) {
381 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
382 __FUNCTION__);
383 return false;
384 }
385
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500386 if(isSecuring(ctx)) {
387 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
388 return false;
389 }
390
Naseer Ahmed76e313c2012-12-01 18:12:59 -0500391 if(ctx->mSecureMode)
392 return false;
393
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500394 //Check for skip layers
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800395 if(isSkipPresent(ctx, dpy)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500396 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530397 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700398 }
399
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800400 if(ctx->listStats[dpy].needsAlphaScale) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500401 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
402 return false;
403 }
404
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700405 //FB composition on idle timeout
406 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500407 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700408 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
409 return false;
410 }
411
Saurabh Shah09549f62012-10-04 13:25:44 -0700412 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700413 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700414 // As MDP h/w supports flip operation, use MDP comp only for
415 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500416 hwc_layer_1_t* layer = &list->hwLayers[i];
417 private_handle_t *hnd = (private_handle_t *)layer->handle;
418 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
419 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
420 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700421 }
422 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700423 return true;
424}
425
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800426int MDPCompLowRes::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
427 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500428 overlay::Overlay& ov = *ctx->mOverlay;
429 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700430
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500431 switch(type) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800432 case MDPCOMP_OV_ANY:
433 case MDPCOMP_OV_RGB:
434 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
435 if(mdp_pipe != ovutils::OV_INVALID) {
436 return mdp_pipe;
437 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700438
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800439 if(type == MDPCOMP_OV_RGB) {
440 //Requested only for RGB pipe
441 return -1;
442 }
443 case MDPCOMP_OV_VG:
444 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
445 if(mdp_pipe != ovutils::OV_INVALID) {
446 return mdp_pipe;
447 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500448 return -1;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800449 default:
450 ALOGE("%s: Invalid pipe type",__FUNCTION__);
451 return -1;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500452 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700453}
454
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800455bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700456 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500457 FrameInfo& currentFrame) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800458 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500459 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800460 int layer_count = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700461
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500462 currentFrame.count = layer_count;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500463 currentFrame.pipeLayer = (PipeLayerPair*)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800464 malloc(sizeof(PipeLayerPair) * currentFrame.count);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500465
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800466 if(isYuvPresent(ctx, dpy)) {
467 int nYuvIndex = ctx->listStats[dpy].yuvIndex;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500468 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
469 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
470 MdpPipeInfo& pipe_info = info.pipeIndex;
471 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
472 if(pipe_info.index < 0) {
473 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800474 __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500475 return false;
476 }
477 pipe_info.zOrder = nYuvIndex;
478 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700479
480 for(int index = 0 ; index < layer_count ; index++ ) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800481 if(index == ctx->listStats[dpy].yuvIndex )
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500482 continue;
483
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700484 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500485 PipeLayerPair& info = currentFrame.pipeLayer[index];
486 MdpPipeInfo& pipe_info = info.pipeIndex;
487 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
488 if(pipe_info.index < 0) {
489 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
490 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700491 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500492 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700493 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700494 return true;
495}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700496
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800497bool MDPCompLowRes::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
498 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700499 int nPipeIndex, vsync_wait, isFG;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800500 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700501
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800502 FrameInfo &currentFrame = mCurrentFrame;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500503 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700504
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500505 if(currentFrame.pipeLayer) {
506 free(currentFrame.pipeLayer);
507 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400508 }
509
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700510 if(!ctx) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800511 ALOGE("%s: invalid context", __FUNCTION__);
512 return -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700513 }
514
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500515 if(!allocLayerPipes(ctx, list, currentFrame)) {
516 //clean current frame data
517 currentFrame.count = 0;
518
519 if(currentFrame.pipeLayer) {
520 free(currentFrame.pipeLayer);
521 currentFrame.pipeLayer = NULL;
522 }
523
524 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
525 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700526 }
527
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500528 for (int index = 0 ; index < currentFrame.count; index++) {
529 hwc_layer_1_t* layer = &list->hwLayers[index];
530 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700531
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800532 if(configure(ctx, layer, cur_pipe) != 0 ) {
533 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
534 layer %d with pipe index:%d",__FUNCTION__,
535 index, cur_pipe.index);
536 return false;
537 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700538 }
539 return true;
540}
541
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800542bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700543
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500544 if(!isEnabled() || !isUsed()) {
545 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
546 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800547 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700548
549 if(!ctx || !list) {
550 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500551 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700552 }
553
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500554 /* reset Invalidator */
555 if(idleInvalidator)
556 idleInvalidator->markForSleep();
557
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800558 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500559 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800560 LayerProp *layerProp = ctx->layerProp[dpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700561
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800562 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700563 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700564 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700565 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700566
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500567 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700568 continue;
569 }
570
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500571 MdpPipeInfo& pipe_info =
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800572 mCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700573 int index = pipe_info.index;
574
575 if(index < 0) {
576 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500577 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700578 }
579
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500580 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700581
582 if (ctx ) {
583 private_handle_t *hnd = (private_handle_t *)layer->handle;
584 if(!hnd) {
585 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500586 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700587 }
588
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700589 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800590 using pipe: %d", __FUNCTION__, layer,
591 hnd, index );
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700592
593 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
594 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500595 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700596 }
597 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500598
599 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700600 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500601 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700602}
603
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800604bool MDPCompLowRes::prepare(hwc_context_t *ctx,
605 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700606 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500607 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700608 return false;
609 }
610
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500611 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700612 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500613 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700614
615 if(doable) {
616 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500617 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700618 } else {
619 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
620 isMDPCompUsed = false;
621 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800622 } else {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700623 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800624 doable);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700625 isMDPCompUsed = false;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800626 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700627
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800628 //Reset states
629 if(!isMDPCompUsed) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700630 //Reset current frame
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800631 reset(ctx, list);
632 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700633
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800634 mState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
635 return isMDPCompUsed;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700636}
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500637
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700638}; //namespace
639