blob: 2c0a77a8487a6a2b6c1fbe7762f3f45c8d57cd04 [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;
Jeykumar Sankaranccb44602013-01-03 12:48:22 -0800372 int availablePipes = ov.availablePipes(dpy);
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800373
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
Amara Venkata Mastan Manoj Kumar75526f52012-12-27 18:27:01 -0800379 if(ctx->mExtDispConfiguring) {
380 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
381 __FUNCTION__);
382 return false;
383 }
384
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500385 if(isSecuring(ctx)) {
386 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
387 return false;
388 }
389
Naseer Ahmed76e313c2012-12-01 18:12:59 -0500390 if(ctx->mSecureMode)
391 return false;
392
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500393 //Check for skip layers
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800394 if(isSkipPresent(ctx, dpy)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500395 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530396 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700397 }
398
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800399 if(ctx->listStats[dpy].needsAlphaScale) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500400 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
401 return false;
402 }
403
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700404 //FB composition on idle timeout
405 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500406 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700407 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
408 return false;
409 }
410
Saurabh Shah09549f62012-10-04 13:25:44 -0700411 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700412 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700413 // As MDP h/w supports flip operation, use MDP comp only for
414 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500415 hwc_layer_1_t* layer = &list->hwLayers[i];
416 private_handle_t *hnd = (private_handle_t *)layer->handle;
417 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
418 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
419 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700420 }
421 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700422 return true;
423}
424
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800425int MDPCompLowRes::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
426 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500427 overlay::Overlay& ov = *ctx->mOverlay;
428 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700429
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500430 switch(type) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800431 case MDPCOMP_OV_ANY:
432 case MDPCOMP_OV_RGB:
433 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
434 if(mdp_pipe != ovutils::OV_INVALID) {
435 return mdp_pipe;
436 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700437
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800438 if(type == MDPCOMP_OV_RGB) {
439 //Requested only for RGB pipe
440 return -1;
441 }
442 case MDPCOMP_OV_VG:
443 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
444 if(mdp_pipe != ovutils::OV_INVALID) {
445 return mdp_pipe;
446 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500447 return -1;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800448 default:
449 ALOGE("%s: Invalid pipe type",__FUNCTION__);
450 return -1;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500451 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700452}
453
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800454bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700455 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500456 FrameInfo& currentFrame) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800457 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500458 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800459 int layer_count = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700460
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500461 currentFrame.count = layer_count;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500462 currentFrame.pipeLayer = (PipeLayerPair*)
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800463 malloc(sizeof(PipeLayerPair) * currentFrame.count);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500464
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800465 if(isYuvPresent(ctx, dpy)) {
466 int nYuvIndex = ctx->listStats[dpy].yuvIndex;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500467 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
468 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
469 MdpPipeInfo& pipe_info = info.pipeIndex;
470 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
471 if(pipe_info.index < 0) {
472 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800473 __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500474 return false;
475 }
476 pipe_info.zOrder = nYuvIndex;
477 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700478
479 for(int index = 0 ; index < layer_count ; index++ ) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800480 if(index == ctx->listStats[dpy].yuvIndex )
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500481 continue;
482
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700483 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500484 PipeLayerPair& info = currentFrame.pipeLayer[index];
485 MdpPipeInfo& pipe_info = info.pipeIndex;
486 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
487 if(pipe_info.index < 0) {
488 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
489 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700490 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500491 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700492 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700493 return true;
494}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700495
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800496bool MDPCompLowRes::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
497 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700498 int nPipeIndex, vsync_wait, isFG;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800499 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700500
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800501 FrameInfo &currentFrame = mCurrentFrame;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500502 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700503
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500504 if(currentFrame.pipeLayer) {
505 free(currentFrame.pipeLayer);
506 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400507 }
508
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700509 if(!ctx) {
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800510 ALOGE("%s: invalid context", __FUNCTION__);
511 return -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700512 }
513
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500514 if(!allocLayerPipes(ctx, list, currentFrame)) {
515 //clean current frame data
516 currentFrame.count = 0;
517
518 if(currentFrame.pipeLayer) {
519 free(currentFrame.pipeLayer);
520 currentFrame.pipeLayer = NULL;
521 }
522
523 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
524 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700525 }
526
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500527 for (int index = 0 ; index < currentFrame.count; index++) {
528 hwc_layer_1_t* layer = &list->hwLayers[index];
529 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700530
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800531 if(configure(ctx, layer, cur_pipe) != 0 ) {
532 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
533 layer %d with pipe index:%d",__FUNCTION__,
534 index, cur_pipe.index);
535 return false;
536 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700537 }
538 return true;
539}
540
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800541bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700542
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500543 if(!isEnabled() || !isUsed()) {
544 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
545 return true;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800546 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700547
548 if(!ctx || !list) {
549 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500550 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700551 }
552
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500553 /* reset Invalidator */
554 if(idleInvalidator)
555 idleInvalidator->markForSleep();
556
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800557 const int dpy = HWC_DISPLAY_PRIMARY;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500558 overlay::Overlay& ov = *ctx->mOverlay;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800559 LayerProp *layerProp = ctx->layerProp[dpy];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700560
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800561 int numHwLayers = ctx->listStats[dpy].numAppLayers;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700562 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700563 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700564 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700565
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500566 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700567 continue;
568 }
569
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500570 MdpPipeInfo& pipe_info =
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800571 mCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700572 int index = pipe_info.index;
573
574 if(index < 0) {
575 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500576 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700577 }
578
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500579 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700580
581 if (ctx ) {
582 private_handle_t *hnd = (private_handle_t *)layer->handle;
583 if(!hnd) {
584 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500585 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700586 }
587
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700588 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800589 using pipe: %d", __FUNCTION__, layer,
590 hnd, index );
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700591
592 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
593 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500594 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700595 }
596 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500597
598 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700599 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500600 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700601}
602
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800603bool MDPCompLowRes::prepare(hwc_context_t *ctx,
604 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700605 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500606 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700607 return false;
608 }
609
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500610 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700611 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500612 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700613
614 if(doable) {
615 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500616 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700617 } else {
618 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
619 isMDPCompUsed = false;
620 }
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800621 } else {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700622 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800623 doable);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700624 isMDPCompUsed = false;
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800625 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700626
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800627 //Reset states
628 if(!isMDPCompUsed) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700629 //Reset current frame
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800630 reset(ctx, list);
631 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700632
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800633 mState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
634 return isMDPCompUsed;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700635}
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500636
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700637}; //namespace
638