blob: 7c2b2bc9b7f3955935b52b5ee43fcda932a5631d [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 Radhakrishnan47573e22012-11-07 11:36:41 -0800218 if((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
219 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
220 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500221}
222
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700223/*
224 * Configures pipe(s) for MDP composition
225 */
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800226int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
227 MdpPipeInfo& mdp_info) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228 int nPipeIndex = mdp_info.index;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800229 const int dpy = HWC_DISPLAY_PRIMARY;
230 private_handle_t *hnd = (private_handle_t *)layer->handle;
231 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800233 if(!hnd) {
234 ALOGE("%s: layer handle is NULL", __FUNCTION__);
235 return -1;
236 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700237
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800238 int hw_w = ctx->dpyAttr[dpy].xres;
239 int hw_h = ctx->dpyAttr[dpy].yres;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700240
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800241 hwc_rect_t sourceCrop = layer->sourceCrop;
242 hwc_rect_t displayFrame = layer->displayFrame;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700243
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800244 const int src_w = sourceCrop.right - sourceCrop.left;
245 const int src_h = sourceCrop.bottom - sourceCrop.top;
246
247 hwc_rect_t crop = sourceCrop;
248 int crop_w = crop.right - crop.left;
249 int crop_h = crop.bottom - crop.top;
250
251 hwc_rect_t dst = displayFrame;
252 int dst_w = dst.right - dst.left;
253 int dst_h = dst.bottom - dst.top;
254
255 if(dst.left < 0 || dst.top < 0 ||
256 dst.right > hw_w || dst.bottom > hw_h) {
257 ALOGD_IF(isDebug(),"%s: Destination has negative coordinates",
258 __FUNCTION__);
259 qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, 0);
260
261 //Update calulated width and height
262 crop_w = crop.right - crop.left;
263 crop_h = crop.bottom - crop.top;
264
265 dst_w = dst.right - dst.left;
266 dst_h = dst.bottom - dst.top;
267 }
268
269 if( (dst_w > hw_w)|| (dst_h > hw_h)) {
270 ALOGD_IF(isDebug(),"%s: Dest rect exceeds FB", __FUNCTION__);
271 printInfo(layer);
272 dst_w = hw_w;
273 dst_h = hw_h;
274 }
275
276 // Determine pipe to set based on pipe index
277 ovutils::eDest dest = (ovutils::eDest)mdp_info.index;
278
279 ovutils::eZorder zOrder = ovutils::ZORDER_0;
280
281 if(mdp_info.zOrder == 0 ) {
282 zOrder = ovutils::ZORDER_0;
283 } else if(mdp_info.zOrder == 1 ) {
284 zOrder = ovutils::ZORDER_1;
285 } else if(mdp_info.zOrder == 2 ) {
286 zOrder = ovutils::ZORDER_2;
287 } else if(mdp_info.zOrder == 3) {
288 zOrder = ovutils::ZORDER_3;
289 }
290
291 // Order order order
292 // setSource - just setting source
293 // setParameter - changes src w/h/f accordingly
294 // setCrop - ROI - src_rect
295 // setPosition - dst_rect
296 // commit - commit changes to mdp driver
297 // queueBuffer - not here, happens when draw is called
298
299 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
300
301 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
302
303 if(isYuvBuffer(hnd))
304 setVidInfo(layer, mdpFlags);
305
306 ovutils::setMdpFlags(mdpFlags,ovutils::OV_MDP_BACKEND_COMPOSITION);
307
308 if(layer->blending == HWC_BLENDING_PREMULT) {
309 ovutils::setMdpFlags(mdpFlags,
310 ovutils::OV_MDP_BLEND_FG_PREMULT);
311 }
312
313 ovutils::eTransform orient = overlay::utils::OVERLAY_TRANSFORM_0 ;
314
315 if(!(layer->transform & HWC_TRANSFORM_ROT_90)) {
316 if(layer->transform & HWC_TRANSFORM_FLIP_H) {
317 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700318 }
319
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800320 if(layer->transform & HWC_TRANSFORM_FLIP_V) {
321 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700322 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800323 } else {
324 orient = static_cast<ovutils::eTransform>(layer->transform);
325 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700326
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800327 ovutils::PipeArgs parg(mdpFlags,
328 info,
329 zOrder,
330 ovutils::IS_FG_OFF,
331 ovutils::ROT_FLAG_DISABLED);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700332
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800333 ov.setSource(parg, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700334
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800335 ov.setTransform(orient, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700336
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800337 ovutils::Dim dcrop(crop.left, crop.top, crop_w, crop_h);
338 ov.setCrop(dcrop, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700339
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800340 ovutils::Dim dim(dst.left, dst.top, dst_w, dst_h);
341 ov.setPosition(dim, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700342
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800343 ALOGD_IF(isDebug(),"%s: MDP set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] \
344 nPipe: %d zorder: %d",__FUNCTION__, dcrop.x,
345 dcrop.y,dcrop.w, dcrop.h, dim.x, dim.y, dim.w, dim.h,
346 mdp_info.index, mdp_info.zOrder);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500347
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800348 if (!ov.commit(dest)) {
349 ALOGE("%s: commit failed", __FUNCTION__);
350 return -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700351 }
352 return 0;
353}
354
355/*
356 * MDPComp not possible when
357 * 1. We have more than sMaxLayers
358 * 2. External display connected
359 * 3. Composition is triggered by
360 * Idle timer expiry
361 * 4. Rotation is needed
362 * 5. Overlay in use
363 */
364
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800365bool MDPCompLowRes::isDoable(hwc_context_t *ctx,
366 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700367 //Number of layers
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800368 const int dpy = HWC_DISPLAY_PRIMARY;
369 int numAppLayers = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500370
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800371 overlay::Overlay& ov = *ctx->mOverlay;
372 int availablePipes = ov.availablePipes();
373
374 if(numAppLayers < 1 || numAppLayers > (uint32_t)availablePipes) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700375 ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
376 return false;
377 }
378
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500379 if(isSecuring(ctx)) {
380 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
381 return false;
382 }
383
Naseer Ahmed76e313c2012-12-01 18:12:59 -0500384 if(ctx->mSecureMode)
385 return false;
386
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500387 //Check for skip layers
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800388 if(isSkipPresent(ctx, dpy)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500389 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530390 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700391 }
392
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800393 if(ctx->listStats[dpy].needsAlphaScale) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500394 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
395 return false;
396 }
397
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700398 //FB composition on idle timeout
399 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500400 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700401 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
402 return false;
403 }
404
Saurabh Shah09549f62012-10-04 13:25:44 -0700405 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700406 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700407 // As MDP h/w supports flip operation, use MDP comp only for
408 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500409 hwc_layer_1_t* layer = &list->hwLayers[i];
410 private_handle_t *hnd = (private_handle_t *)layer->handle;
411 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
412 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
413 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700414 }
415 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700416 return true;
417}
418
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800419int MDPCompLowRes::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
420 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500421 overlay::Overlay& ov = *ctx->mOverlay;
422 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700423
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500424 switch(type) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800425 case MDPCOMP_OV_ANY:
426 case MDPCOMP_OV_RGB:
427 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
428 if(mdp_pipe != ovutils::OV_INVALID) {
429 return mdp_pipe;
430 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700431
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800432 if(type == MDPCOMP_OV_RGB) {
433 //Requested only for RGB pipe
434 return -1;
435 }
436 case MDPCOMP_OV_VG:
437 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
438 if(mdp_pipe != ovutils::OV_INVALID) {
439 return mdp_pipe;
440 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500441 return -1;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800442 default:
443 ALOGE("%s: Invalid pipe type",__FUNCTION__);
444 return -1;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500445 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700446}
447
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800448bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700449 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500450 FrameInfo& currentFrame) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800451 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500452 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800453 int layer_count = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700454
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500455 currentFrame.count = layer_count;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500456 currentFrame.pipeLayer = (PipeLayerPair*)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800457 malloc(sizeof(PipeLayerPair) * currentFrame.count);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500458
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800459 if(isYuvPresent(ctx, dpy)) {
460 int nYuvIndex = ctx->listStats[dpy].yuvIndex;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500461 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
462 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
463 MdpPipeInfo& pipe_info = info.pipeIndex;
464 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
465 if(pipe_info.index < 0) {
466 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800467 __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500468 return false;
469 }
470 pipe_info.zOrder = nYuvIndex;
471 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700472
473 for(int index = 0 ; index < layer_count ; index++ ) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800474 if(index == ctx->listStats[dpy].yuvIndex )
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500475 continue;
476
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700477 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500478 PipeLayerPair& info = currentFrame.pipeLayer[index];
479 MdpPipeInfo& pipe_info = info.pipeIndex;
480 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
481 if(pipe_info.index < 0) {
482 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
483 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700484 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500485 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700486 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700487 return true;
488}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700489
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800490bool MDPCompLowRes::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
491 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700492 int nPipeIndex, vsync_wait, isFG;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800493 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700494
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800495 FrameInfo &currentFrame = mCurrentFrame;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500496 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700497
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500498 if(currentFrame.pipeLayer) {
499 free(currentFrame.pipeLayer);
500 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400501 }
502
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700503 if(!ctx) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800504 ALOGE("%s: invalid context", __FUNCTION__);
505 return -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700506 }
507
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500508 if(!allocLayerPipes(ctx, list, currentFrame)) {
509 //clean current frame data
510 currentFrame.count = 0;
511
512 if(currentFrame.pipeLayer) {
513 free(currentFrame.pipeLayer);
514 currentFrame.pipeLayer = NULL;
515 }
516
517 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
518 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700519 }
520
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500521 for (int index = 0 ; index < currentFrame.count; index++) {
522 hwc_layer_1_t* layer = &list->hwLayers[index];
523 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700524
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800525 if(configure(ctx, layer, cur_pipe) != 0 ) {
526 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
527 layer %d with pipe index:%d",__FUNCTION__,
528 index, cur_pipe.index);
529 return false;
530 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700531 }
532 return true;
533}
534
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800535bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700536
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500537 if(!isEnabled() || !isUsed()) {
538 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
539 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800540 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700541
542 if(!ctx || !list) {
543 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500544 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700545 }
546
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500547 /* reset Invalidator */
548 if(idleInvalidator)
549 idleInvalidator->markForSleep();
550
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800551 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500552 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800553 LayerProp *layerProp = ctx->layerProp[dpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700554
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800555 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700556 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700557 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700558 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700559
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500560 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700561 continue;
562 }
563
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500564 MdpPipeInfo& pipe_info =
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800565 mCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700566 int index = pipe_info.index;
567
568 if(index < 0) {
569 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500570 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700571 }
572
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500573 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700574
575 if (ctx ) {
576 private_handle_t *hnd = (private_handle_t *)layer->handle;
577 if(!hnd) {
578 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500579 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700580 }
581
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700582 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800583 using pipe: %d", __FUNCTION__, layer,
584 hnd, index );
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700585
586 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
587 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500588 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700589 }
590 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500591
592 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700593 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500594 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700595}
596
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800597bool MDPCompLowRes::prepare(hwc_context_t *ctx,
598 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700599 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500600 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700601 return false;
602 }
603
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500604 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700605 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500606 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700607
608 if(doable) {
609 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500610 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700611 } else {
612 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
613 isMDPCompUsed = false;
614 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800615 } else {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700616 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800617 doable);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700618 isMDPCompUsed = false;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800619 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700620
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800621 //Reset states
622 if(!isMDPCompUsed) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700623 //Reset current frame
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800624 reset(ctx, list);
625 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700626
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800627 mState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
628 return isMDPCompUsed;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700629}
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500630
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700631}; //namespace
632