blob: bbea0079d7afd3635cc6835772eeeb67d9ea6e5a [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"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080023#include "mdp_version.h"
Naseer Ahmed7c958d42012-07-31 18:57:03 -070024
Naseer Ahmed7c958d42012-07-31 18:57:03 -070025namespace qhwc {
26
Naseer Ahmed54821fe2012-11-28 18:44:38 -050027namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070028
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080029//==============MDPComp========================================================
30
Naseer Ahmed7c958d42012-07-31 18:57:03 -070031IdleInvalidator *MDPComp::idleInvalidator = NULL;
32bool MDPComp::sIdleFallBack = false;
33bool MDPComp::sDebugLogs = false;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050034bool MDPComp::sEnabled = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070035
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080036MDPComp* MDPComp::getObject(const int& width) {
37 //For now. Later check for width > 2048
38 return new MDPCompLowRes();
39}
40
41void MDPComp::dump(android::String8& buf)
42{
43 dumpsys_log(buf, " MDP Composition: ");
44 dumpsys_log(buf, "MDPCompState=%d\n", mState);
45 //XXX: Log more info
46}
47
48bool MDPComp::init(hwc_context_t *ctx) {
49
50 if(!ctx) {
51 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
52 return false;
53 }
54
55 if(!setupBasePipe(ctx)) {
56 ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
57 return false;
58 }
59
60 char property[PROPERTY_VALUE_MAX];
61
62 sEnabled = false;
63 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
64 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
65 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
66 sEnabled = true;
67 }
68
69 sDebugLogs = false;
70 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
71 if(atoi(property) != 0)
72 sDebugLogs = true;
73 }
74
75 unsigned long idle_timeout = DEFAULT_IDLE_TIME;
76 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
77 if(atoi(property) != 0)
78 idle_timeout = atoi(property);
79 }
80
81 //create Idle Invalidator
82 idleInvalidator = IdleInvalidator::getInstance();
83
84 if(idleInvalidator == NULL) {
85 ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
86 } else {
87 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
88 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -070089 return true;
90}
91
92void MDPComp::timeout_handler(void *udata) {
93 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
94
95 if(!ctx) {
96 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
97 return;
98 }
99
Jesse Hall3be78d92012-08-21 15:12:23 -0700100 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700101 ALOGE("%s: HWC proc not registered", __FUNCTION__);
102 return;
103 }
104 sIdleFallBack = true;
105 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -0700106 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700107}
108
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800109void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
110 hwc_display_contents_1_t* list) {
111 const int dpy = HWC_DISPLAY_PRIMARY;
112 LayerProp *layerProp = ctx->layerProp[dpy];
113
114 for(int index = 0; index < ctx->listStats[dpy].numAppLayers; index++ ) {
115 hwc_layer_1_t* layer = &(list->hwLayers[index]);
116 layerProp[index].mFlags |= HWC_MDPCOMP;
117 layer->compositionType = HWC_OVERLAY;
118 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400119 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700120}
121
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800122void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
123 hwc_display_contents_1_t* list) {
124 const int dpy = HWC_DISPLAY_PRIMARY;
125 LayerProp *layerProp = ctx->layerProp[dpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700126
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800127 for (int index = 0 ;
128 index < ctx->listStats[dpy].numAppLayers; index++) {
129 if(layerProp[index].mFlags & HWC_MDPCOMP) {
130 layerProp[index].mFlags &= ~HWC_MDPCOMP;
131 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700132
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800133 if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
134 list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
135 }
136 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700137}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500138
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800139/*
140 * Sets up BORDERFILL as default base pipe and detaches RGB0.
141 * Framebuffer is always updated using PLAY ioctl.
142 */
143bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
144 const int dpy = HWC_DISPLAY_PRIMARY;
145 int fb_stride = ctx->dpyAttr[dpy].stride;
146 int fb_width = ctx->dpyAttr[dpy].xres;
147 int fb_height = ctx->dpyAttr[dpy].yres;
148 int fb_fd = ctx->dpyAttr[dpy].fd;
149
150 mdp_overlay ovInfo;
151 msmfb_overlay_data ovData;
152 memset(&ovInfo, 0, sizeof(mdp_overlay));
153 memset(&ovData, 0, sizeof(msmfb_overlay_data));
154
155 ovInfo.src.format = MDP_RGB_BORDERFILL;
156 ovInfo.src.width = fb_width;
157 ovInfo.src.height = fb_height;
158 ovInfo.src_rect.w = fb_width;
159 ovInfo.src_rect.h = fb_height;
160 ovInfo.dst_rect.w = fb_width;
161 ovInfo.dst_rect.h = fb_height;
162 ovInfo.id = MSMFB_NEW_REQUEST;
163
164 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
165 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
166 strerror(errno));
167 return false;
168 }
169
170 ovData.id = ovInfo.id;
171 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
172 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
173 strerror(errno));
174 return false;
175 }
176 return true;
177}
178
179void MDPComp::printInfo(hwc_layer_1_t* layer) {
180 hwc_rect_t sourceCrop = layer->sourceCrop;
181 hwc_rect_t displayFrame = layer->displayFrame;
182
183 int s_l = sourceCrop.left;
184 int s_t = sourceCrop.top;
185 int s_r = sourceCrop.right;
186 int s_b = sourceCrop.bottom;
187
188 int d_l = displayFrame.left;
189 int d_t = displayFrame.top;
190 int d_r = displayFrame.right;
191 int d_b = displayFrame.bottom;
192
193 ALOGD_IF(isDebug(), "src:[%d,%d,%d,%d] (%d x %d) \
194 dst:[%d,%d,%d,%d] (%d x %d)",
195 s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
196 d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
197}
198
199//=============MDPCompLowRes===================================================
200void MDPCompLowRes::reset(hwc_context_t *ctx,
201 hwc_display_contents_1_t* list ) {
202 //Reset flags and states
203 unsetMDPCompLayerFlags(ctx, list);
204 mCurrentFrame.count = 0;
205 if(mCurrentFrame.pipeLayer) {
206 free(mCurrentFrame.pipeLayer);
207 mCurrentFrame.pipeLayer = NULL;
208 }
209}
210
211void MDPCompLowRes::setVidInfo(hwc_layer_1_t *layer,
212 ovutils::eMdpFlags &mdpFlags) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500213 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800214 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500215
216 if(isSecureBuffer(hnd)) {
217 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500218 }
Ramkumar Radhakrishnan12b103b2013-01-09 17:47:56 -0800219 if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
220 metadata->interlaced) {
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800221 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
222 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500223}
224
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700225/*
226 * Configures pipe(s) for MDP composition
227 */
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800228int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
229 MdpPipeInfo& mdp_info) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700230 int nPipeIndex = mdp_info.index;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800231 const int dpy = HWC_DISPLAY_PRIMARY;
232 private_handle_t *hnd = (private_handle_t *)layer->handle;
233 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700234
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800235 if(!hnd) {
236 ALOGE("%s: layer handle is NULL", __FUNCTION__);
237 return -1;
238 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700239
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800240 int hw_w = ctx->dpyAttr[dpy].xres;
241 int hw_h = ctx->dpyAttr[dpy].yres;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700242
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800243 hwc_rect_t sourceCrop = layer->sourceCrop;
244 hwc_rect_t displayFrame = layer->displayFrame;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700245
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800246 const int src_w = sourceCrop.right - sourceCrop.left;
247 const int src_h = sourceCrop.bottom - sourceCrop.top;
248
249 hwc_rect_t crop = sourceCrop;
250 int crop_w = crop.right - crop.left;
251 int crop_h = crop.bottom - crop.top;
252
253 hwc_rect_t dst = displayFrame;
254 int dst_w = dst.right - dst.left;
255 int dst_h = dst.bottom - dst.top;
256
257 if(dst.left < 0 || dst.top < 0 ||
258 dst.right > hw_w || dst.bottom > hw_h) {
259 ALOGD_IF(isDebug(),"%s: Destination has negative coordinates",
260 __FUNCTION__);
261 qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, 0);
262
263 //Update calulated width and height
264 crop_w = crop.right - crop.left;
265 crop_h = crop.bottom - crop.top;
266
267 dst_w = dst.right - dst.left;
268 dst_h = dst.bottom - dst.top;
269 }
270
271 if( (dst_w > hw_w)|| (dst_h > hw_h)) {
272 ALOGD_IF(isDebug(),"%s: Dest rect exceeds FB", __FUNCTION__);
273 printInfo(layer);
274 dst_w = hw_w;
275 dst_h = hw_h;
276 }
277
278 // Determine pipe to set based on pipe index
279 ovutils::eDest dest = (ovutils::eDest)mdp_info.index;
280
281 ovutils::eZorder zOrder = ovutils::ZORDER_0;
282
283 if(mdp_info.zOrder == 0 ) {
284 zOrder = ovutils::ZORDER_0;
285 } else if(mdp_info.zOrder == 1 ) {
286 zOrder = ovutils::ZORDER_1;
287 } else if(mdp_info.zOrder == 2 ) {
288 zOrder = ovutils::ZORDER_2;
289 } else if(mdp_info.zOrder == 3) {
290 zOrder = ovutils::ZORDER_3;
291 }
292
293 // Order order order
294 // setSource - just setting source
295 // setParameter - changes src w/h/f accordingly
296 // setCrop - ROI - src_rect
297 // setPosition - dst_rect
298 // commit - commit changes to mdp driver
299 // queueBuffer - not here, happens when draw is called
300
301 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
302
303 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
304
305 if(isYuvBuffer(hnd))
306 setVidInfo(layer, mdpFlags);
307
308 ovutils::setMdpFlags(mdpFlags,ovutils::OV_MDP_BACKEND_COMPOSITION);
309
310 if(layer->blending == HWC_BLENDING_PREMULT) {
311 ovutils::setMdpFlags(mdpFlags,
312 ovutils::OV_MDP_BLEND_FG_PREMULT);
313 }
314
315 ovutils::eTransform orient = overlay::utils::OVERLAY_TRANSFORM_0 ;
316
317 if(!(layer->transform & HWC_TRANSFORM_ROT_90)) {
318 if(layer->transform & HWC_TRANSFORM_FLIP_H) {
319 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700320 }
321
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800322 if(layer->transform & HWC_TRANSFORM_FLIP_V) {
323 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700324 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800325 } else {
326 orient = static_cast<ovutils::eTransform>(layer->transform);
327 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700328
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800329 ovutils::eRotFlags rotFlags = ovutils::ROT_FLAGS_NONE;
330 if(isYuvBuffer(hnd) && (ctx->mMDP.version >= qdutils::MDP_V4_2 &&
331 ctx->mMDP.version < qdutils::MDSS_V5)) {
332 rotFlags = ovutils::ROT_DOWNSCALE_ENABLED;
333 }
334
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800335 ovutils::PipeArgs parg(mdpFlags,
336 info,
337 zOrder,
338 ovutils::IS_FG_OFF,
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800339 rotFlags);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700340
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800341 ov.setSource(parg, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700342
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800343 ov.setTransform(orient, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700344
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800345 ovutils::Dim dcrop(crop.left, crop.top, crop_w, crop_h);
346 ov.setCrop(dcrop, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700347
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800348 ovutils::Dim dim(dst.left, dst.top, dst_w, dst_h);
349 ov.setPosition(dim, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700350
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800351 ALOGD_IF(isDebug(),"%s: MDP set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] \
352 nPipe: %d zorder: %d",__FUNCTION__, dcrop.x,
353 dcrop.y,dcrop.w, dcrop.h, dim.x, dim.y, dim.w, dim.h,
354 mdp_info.index, mdp_info.zOrder);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500355
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800356 if (!ov.commit(dest)) {
357 ALOGE("%s: commit failed", __FUNCTION__);
358 return -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700359 }
360 return 0;
361}
362
363/*
364 * MDPComp not possible when
365 * 1. We have more than sMaxLayers
366 * 2. External display connected
367 * 3. Composition is triggered by
368 * Idle timer expiry
369 * 4. Rotation is needed
370 * 5. Overlay in use
371 */
372
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800373bool MDPCompLowRes::isDoable(hwc_context_t *ctx,
374 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700375 //Number of layers
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800376 const int dpy = HWC_DISPLAY_PRIMARY;
377 int numAppLayers = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500378
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800379 overlay::Overlay& ov = *ctx->mOverlay;
Jeykumar Sankaranccb44602013-01-03 12:48:22 -0800380 int availablePipes = ov.availablePipes(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800381
382 if(numAppLayers < 1 || numAppLayers > (uint32_t)availablePipes) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700383 ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
384 return false;
385 }
386
Amara Venkata Mastan Manoj Kumar75526f52012-12-27 18:27:01 -0800387 if(ctx->mExtDispConfiguring) {
388 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
389 __FUNCTION__);
390 return false;
391 }
392
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500393 if(isSecuring(ctx)) {
394 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
395 return false;
396 }
397
Naseer Ahmed76e313c2012-12-01 18:12:59 -0500398 if(ctx->mSecureMode)
399 return false;
400
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500401 //Check for skip layers
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800402 if(isSkipPresent(ctx, dpy)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500403 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530404 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700405 }
406
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800407 if(ctx->listStats[dpy].needsAlphaScale) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500408 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
409 return false;
410 }
411
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700412 //FB composition on idle timeout
413 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500414 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700415 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
416 return false;
417 }
418
Saurabh Shah09549f62012-10-04 13:25:44 -0700419 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700420 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700421 // As MDP h/w supports flip operation, use MDP comp only for
422 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500423 hwc_layer_1_t* layer = &list->hwLayers[i];
424 private_handle_t *hnd = (private_handle_t *)layer->handle;
425 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
426 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
427 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700428 }
429 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700430 return true;
431}
432
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800433int MDPCompLowRes::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
434 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500435 overlay::Overlay& ov = *ctx->mOverlay;
436 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700437
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500438 switch(type) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800439 case MDPCOMP_OV_ANY:
440 case MDPCOMP_OV_RGB:
441 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
442 if(mdp_pipe != ovutils::OV_INVALID) {
443 return mdp_pipe;
444 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700445
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800446 if(type == MDPCOMP_OV_RGB) {
447 //Requested only for RGB pipe
448 return -1;
449 }
450 case MDPCOMP_OV_VG:
451 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
452 if(mdp_pipe != ovutils::OV_INVALID) {
453 return mdp_pipe;
454 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500455 return -1;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800456 default:
457 ALOGE("%s: Invalid pipe type",__FUNCTION__);
458 return -1;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500459 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700460}
461
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800462bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700463 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500464 FrameInfo& currentFrame) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800465 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500466 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800467 int layer_count = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700468
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500469 currentFrame.count = layer_count;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500470 currentFrame.pipeLayer = (PipeLayerPair*)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800471 malloc(sizeof(PipeLayerPair) * currentFrame.count);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500472
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800473 if(isYuvPresent(ctx, dpy)) {
474 int nYuvIndex = ctx->listStats[dpy].yuvIndex;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500475 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
476 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
477 MdpPipeInfo& pipe_info = info.pipeIndex;
478 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
479 if(pipe_info.index < 0) {
480 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800481 __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500482 return false;
483 }
484 pipe_info.zOrder = nYuvIndex;
485 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700486
487 for(int index = 0 ; index < layer_count ; index++ ) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800488 if(index == ctx->listStats[dpy].yuvIndex )
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500489 continue;
490
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700491 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500492 PipeLayerPair& info = currentFrame.pipeLayer[index];
493 MdpPipeInfo& pipe_info = info.pipeIndex;
494 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
495 if(pipe_info.index < 0) {
496 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
497 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700498 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500499 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700500 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700501 return true;
502}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700503
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800504bool MDPCompLowRes::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
505 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700506 int nPipeIndex, vsync_wait, isFG;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800507 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700508
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800509 FrameInfo &currentFrame = mCurrentFrame;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500510 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700511
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500512 if(currentFrame.pipeLayer) {
513 free(currentFrame.pipeLayer);
514 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400515 }
516
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700517 if(!ctx) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800518 ALOGE("%s: invalid context", __FUNCTION__);
519 return -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700520 }
521
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500522 if(!allocLayerPipes(ctx, list, currentFrame)) {
523 //clean current frame data
524 currentFrame.count = 0;
525
526 if(currentFrame.pipeLayer) {
527 free(currentFrame.pipeLayer);
528 currentFrame.pipeLayer = NULL;
529 }
530
531 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
532 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700533 }
534
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500535 for (int index = 0 ; index < currentFrame.count; index++) {
536 hwc_layer_1_t* layer = &list->hwLayers[index];
537 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700538
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800539 if(configure(ctx, layer, cur_pipe) != 0 ) {
540 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
541 layer %d with pipe index:%d",__FUNCTION__,
542 index, cur_pipe.index);
543 return false;
544 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700545 }
546 return true;
547}
548
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800549bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700550
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500551 if(!isEnabled() || !isUsed()) {
552 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
553 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800554 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700555
556 if(!ctx || !list) {
557 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500558 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700559 }
560
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500561 /* reset Invalidator */
562 if(idleInvalidator)
563 idleInvalidator->markForSleep();
564
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800565 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500566 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800567 LayerProp *layerProp = ctx->layerProp[dpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700568
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800569 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700570 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700571 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700572 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700573
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500574 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700575 continue;
576 }
577
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500578 MdpPipeInfo& pipe_info =
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800579 mCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700580 int index = pipe_info.index;
581
582 if(index < 0) {
583 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500584 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700585 }
586
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500587 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700588
589 if (ctx ) {
590 private_handle_t *hnd = (private_handle_t *)layer->handle;
591 if(!hnd) {
592 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500593 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700594 }
595
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700596 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800597 using pipe: %d", __FUNCTION__, layer,
598 hnd, index );
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700599
600 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
601 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500602 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700603 }
604 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500605
606 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700607 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500608 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700609}
610
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800611bool MDPCompLowRes::prepare(hwc_context_t *ctx,
612 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700613 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500614 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700615 return false;
616 }
617
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500618 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700619 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500620 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700621
622 if(doable) {
623 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500624 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700625 } else {
626 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
627 isMDPCompUsed = false;
628 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800629 } else {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700630 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800631 doable);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700632 isMDPCompUsed = false;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800633 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700634
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800635 //Reset states
636 if(!isMDPCompUsed) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700637 //Reset current frame
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800638 reset(ctx, list);
639 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700640
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800641 mState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
642 return isMDPCompUsed;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700643}
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500644
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700645}; //namespace
646