blob: 45842078790fe3dfceab80459ce96dcc52734887 [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"
Naseer Ahmed7c958d42012-07-31 18:57:03 -070022
Naseer Ahmed7c958d42012-07-31 18:57:03 -070023namespace qhwc {
24
Naseer Ahmed54821fe2012-11-28 18:44:38 -050025namespace ovutils = overlay::utils;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070026/****** Class MDPComp ***********/
27
Naseer Ahmed54821fe2012-11-28 18:44:38 -050028MDPComp::eState MDPComp::sMDPCompState = MDPCOMP_OFF;
29struct MDPComp::FrameInfo MDPComp::sCurrentFrame;
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;
34int MDPComp::sActiveMax = 0;
35bool MDPComp::sSecuredVid = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070036
37bool MDPComp::deinit() {
38 //XXX: Tear down MDP comp state
39 return true;
40}
Naseer Ahmed54821fe2012-11-28 18:44:38 -050041bool MDPComp::isSkipPresent (hwc_context_t *ctx) {
42 return ctx->listStats[HWC_DISPLAY_PRIMARY].skipCount;
43};
44
45bool MDPComp::isYuvPresent (hwc_context_t *ctx) {
46 return ctx->listStats[HWC_DISPLAY_PRIMARY].yuvCount;
47};
Naseer Ahmed7c958d42012-07-31 18:57:03 -070048
49void MDPComp::timeout_handler(void *udata) {
50 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
51
52 if(!ctx) {
53 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
54 return;
55 }
56
Jesse Hall3be78d92012-08-21 15:12:23 -070057 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -070058 ALOGE("%s: HWC proc not registered", __FUNCTION__);
59 return;
60 }
61 sIdleFallBack = true;
62 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -070063 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -070064}
65
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -070066void MDPComp::reset(hwc_context_t *ctx, hwc_display_contents_1_t* list ) {
67 //Reset flags and states
68 unsetMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -070069 sCurrentFrame.count = 0;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050070 if(sCurrentFrame.pipeLayer) {
71 free(sCurrentFrame.pipeLayer);
72 sCurrentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -040073 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -070074}
75
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070076void MDPComp::print_info(hwc_layer_1_t* layer)
Naseer Ahmed7c958d42012-07-31 18:57:03 -070077{
78 hwc_rect_t sourceCrop = layer->sourceCrop;
79 hwc_rect_t displayFrame = layer->displayFrame;
80
81 int s_l = sourceCrop.left;
82 int s_t = sourceCrop.top;
83 int s_r = sourceCrop.right;
84 int s_b = sourceCrop.bottom;
85
86 int d_l = displayFrame.left;
87 int d_t = displayFrame.top;
88 int d_r = displayFrame.right;
89 int d_b = displayFrame.bottom;
90
91 ALOGD_IF(isDebug(), "src:[%d,%d,%d,%d] (%d x %d) \
92 dst:[%d,%d,%d,%d] (%d x %d)",
93 s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
94 d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
95}
Naseer Ahmed54821fe2012-11-28 18:44:38 -050096
97void MDPComp::setVidInfo(hwc_layer_1_t *layer, ovutils::eMdpFlags &mdpFlags) {
98 private_handle_t *hnd = (private_handle_t *)layer->handle;
99
100 if(isSecureBuffer(hnd)) {
101 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
102 sSecuredVid = true;
103 }
104}
105
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700106/*
107 * Configures pipe(s) for MDP composition
108 */
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700109int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500110 MdpPipeInfo& mdp_info) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700111
112 int nPipeIndex = mdp_info.index;
113
114 if (ctx) {
115
116 private_handle_t *hnd = (private_handle_t *)layer->handle;
117
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500118 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700119
120 if(!hnd) {
121 ALOGE("%s: layer handle is NULL", __FUNCTION__);
122 return -1;
123 }
124
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500125 int hw_w = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
126 int hw_h = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700127
128 hwc_rect_t sourceCrop = layer->sourceCrop;
129 hwc_rect_t displayFrame = layer->displayFrame;
130
131 const int src_w = sourceCrop.right - sourceCrop.left;
132 const int src_h = sourceCrop.bottom - sourceCrop.top;
133
134 hwc_rect_t crop = sourceCrop;
135 int crop_w = crop.right - crop.left;
136 int crop_h = crop.bottom - crop.top;
137
138 hwc_rect_t dst = displayFrame;
139 int dst_w = dst.right - dst.left;
140 int dst_h = dst.bottom - dst.top;
141
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700142 if(dst.left < 0 || dst.top < 0 ||
143 dst.right > hw_w || dst.bottom > hw_h) {
144 ALOGD_IF(isDebug(),"%s: Destination has negative coordinates",
145 __FUNCTION__);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700146 qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, 0);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700147
148 //Update calulated width and height
149 crop_w = crop.right - crop.left;
150 crop_h = crop.bottom - crop.top;
151
152 dst_w = dst.right - dst.left;
153 dst_h = dst.bottom - dst.top;
154 }
155
156 if( (dst_w > hw_w)|| (dst_h > hw_h)) {
157 ALOGD_IF(isDebug(),"%s: Dest rect exceeds FB", __FUNCTION__);
158 print_info(layer);
159 dst_w = hw_w;
160 dst_h = hw_h;
161 }
162
163 // Determine pipe to set based on pipe index
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500164 ovutils::eDest dest = (ovutils::eDest)mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700165
166 ovutils::eZorder zOrder = ovutils::ZORDER_0;
167
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500168 if(mdp_info.zOrder == 0 ) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700169 zOrder = ovutils::ZORDER_0;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500170 } else if(mdp_info.zOrder == 1 ) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700171 zOrder = ovutils::ZORDER_1;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500172 } else if(mdp_info.zOrder == 2 ) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700173 zOrder = ovutils::ZORDER_2;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500174 } else if(mdp_info.zOrder == 3) {
175 zOrder = ovutils::ZORDER_3;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700176 }
177
178 // Order order order
179 // setSource - just setting source
180 // setParameter - changes src w/h/f accordingly
181 // setCrop - ROI - src_rect
182 // setPosition - dst_rect
183 // commit - commit changes to mdp driver
184 // queueBuffer - not here, happens when draw is called
185
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700186 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500187
188 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
189
190 if(isYuvBuffer(hnd))
191 setVidInfo(layer, mdpFlags);
192
Saurabh Shah799a3972012-09-01 12:16:12 -0700193 ovutils::setMdpFlags(mdpFlags,ovutils::OV_MDP_BACKEND_COMPOSITION);
Saurabh Shah91a6a992012-08-20 15:25:28 -0700194
195 if(layer->blending == HWC_BLENDING_PREMULT) {
196 ovutils::setMdpFlags(mdpFlags,
197 ovutils::OV_MDP_BLEND_FG_PREMULT);
198 }
199
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500200 ovutils::eTransform orient = overlay::utils::OVERLAY_TRANSFORM_0 ;
Saurabh Shah09549f62012-10-04 13:25:44 -0700201
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500202 if(!(layer->transform & HWC_TRANSFORM_ROT_90)) {
203 if(layer->transform & HWC_TRANSFORM_FLIP_H) {
204 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
205 }
Saurabh Shah09549f62012-10-04 13:25:44 -0700206
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500207 if(layer->transform & HWC_TRANSFORM_FLIP_V) {
208 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
209 }
210 } else {
211 orient = static_cast<ovutils::eTransform>(layer->transform);
212 }
Saurabh Shah09549f62012-10-04 13:25:44 -0700213
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700214 ovutils::PipeArgs parg(mdpFlags,
215 info,
216 zOrder,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500217 ovutils::IS_FG_OFF,
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700218 ovutils::ROT_FLAG_DISABLED);
219
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500220 ov.setSource(parg, dest);
221
222 ov.setTransform(orient, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700223
224 ovutils::Dim dcrop(crop.left, crop.top, crop_w, crop_h);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500225 ov.setCrop(dcrop, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700226
227 ovutils::Dim dim(dst.left, dst.top, dst_w, dst_h);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500228 ov.setPosition(dim, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700229
230 ALOGD_IF(isDebug(),"%s: MDP set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] \
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500231 nPipe: %d zorder: %d",__FUNCTION__, dcrop.x,
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700232 dcrop.y,dcrop.w, dcrop.h, dim.x, dim.y, dim.w, dim.h,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500233 mdp_info.index, mdp_info.zOrder);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700234
235 if (!ov.commit(dest)) {
236 ALOGE("%s: commit failed", __FUNCTION__);
237 return -1;
238 }
239 }
240 return 0;
241}
242
243/*
244 * MDPComp not possible when
245 * 1. We have more than sMaxLayers
246 * 2. External display connected
247 * 3. Composition is triggered by
248 * Idle timer expiry
249 * 4. Rotation is needed
250 * 5. Overlay in use
251 */
252
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500253bool MDPComp::isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700254 //Number of layers
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700255 int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500256
257 if(numAppLayers < 1 || numAppLayers > (uint32_t)sActiveMax) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700258 ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
259 return false;
260 }
261
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500262 if(isSecuring(ctx)) {
263 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
264 return false;
265 }
266
Naseer Ahmed76e313c2012-12-01 18:12:59 -0500267 if(ctx->mSecureMode)
268 return false;
269
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500270 //Check for skip layers
271 if(isSkipPresent(ctx)) {
272 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530273 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700274 }
275
276 //FB composition on idle timeout
277 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500278 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700279 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
280 return false;
281 }
282
Saurabh Shah09549f62012-10-04 13:25:44 -0700283 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700284 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700285 // As MDP h/w supports flip operation, use MDP comp only for
286 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500287 hwc_layer_1_t* layer = &list->hwLayers[i];
288 private_handle_t *hnd = (private_handle_t *)layer->handle;
289 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
290 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
291 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700292 }
293 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700294 return true;
295}
296
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500297void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
298 hwc_display_contents_1_t* list) {
299 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700300
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500301 for(int index = 0 ; index < sCurrentFrame.count; index++ ) {
302 hwc_layer_1_t* layer = &(list->hwLayers[index]);
303 layerProp[index].mFlags |= HWC_MDPCOMP;
304 layer->compositionType = HWC_OVERLAY;
305 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700306 }
307}
308
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500309int MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type){
310 overlay::Overlay& ov = *ctx->mOverlay;
311 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700312
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500313 switch(type) {
314 case MDPCOMP_OV_ANY:
315 case MDPCOMP_OV_RGB:
316 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, HWC_DISPLAY_PRIMARY);
317 if(mdp_pipe != ovutils::OV_INVALID) {
318 return mdp_pipe;
319 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700320
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500321 if(type == MDPCOMP_OV_RGB) {
322 //Requested only for RGB pipe
323 return -1;
324 }
325 case MDPCOMP_OV_VG:
326 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, HWC_DISPLAY_PRIMARY);
327 if(mdp_pipe != ovutils::OV_INVALID) {
328 return mdp_pipe;
329 }
330 return -1;
331 default:
332 ALOGE("%s: Invalid pipe type",__FUNCTION__);
333 return -1;
334 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700335}
336
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500337bool MDPComp::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700338 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500339 FrameInfo& currentFrame) {
340
341 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700342
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700343 int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700344
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500345 currentFrame.count = layer_count;
346
347 currentFrame.pipeLayer = (PipeLayerPair*)
348 malloc(sizeof(PipeLayerPair) * currentFrame.count);
349
350 if(isYuvPresent(ctx)) {
351 int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex;
352 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
353 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
354 MdpPipeInfo& pipe_info = info.pipeIndex;
355 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
356 if(pipe_info.index < 0) {
357 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
358 __FUNCTION__);
359 return false;
360 }
361 pipe_info.zOrder = nYuvIndex;
362 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700363
364 for(int index = 0 ; index < layer_count ; index++ ) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500365 if(index == ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex )
366 continue;
367
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700368 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500369 PipeLayerPair& info = currentFrame.pipeLayer[index];
370 MdpPipeInfo& pipe_info = info.pipeIndex;
371 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
372 if(pipe_info.index < 0) {
373 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
374 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700375 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500376 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700377 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700378 return true;
379}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700380
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700381bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700382 int nPipeIndex, vsync_wait, isFG;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700383 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700384
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500385 FrameInfo &currentFrame = sCurrentFrame;
386 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700387
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500388 if(currentFrame.pipeLayer) {
389 free(currentFrame.pipeLayer);
390 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400391 }
392
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700393 if(!ctx) {
394 ALOGE("%s: invalid context", __FUNCTION__);
395 return -1;
396 }
397
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500398 if(!allocLayerPipes(ctx, list, currentFrame)) {
399 //clean current frame data
400 currentFrame.count = 0;
401
402 if(currentFrame.pipeLayer) {
403 free(currentFrame.pipeLayer);
404 currentFrame.pipeLayer = NULL;
405 }
406
407 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
408 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700409 }
410
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500411 for (int index = 0 ; index < currentFrame.count; index++) {
412 hwc_layer_1_t* layer = &list->hwLayers[index];
413 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700414
415 if( prepare(ctx, layer, cur_pipe) != 0 ) {
416 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
417 layer %d with pipe index:%d",__FUNCTION__,
418 index, cur_pipe.index);
419 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700420 }
421 }
422 return true;
423}
424
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500425void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
426 hwc_display_contents_1_t* list)
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700427{
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500428 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
429
Naseer Ahmeda2567482012-11-30 18:27:54 -0500430 for (int index = 0 ;
431 index < ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; index++) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500432 if(layerProp[index].mFlags & HWC_MDPCOMP) {
433 layerProp[index].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700434 }
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700435
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500436 if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
437 list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700438 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700439 }
440}
441
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500442bool MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700443
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500444 if(!isEnabled() || !isUsed()) {
445 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
446 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700447 }
448
449 if(!ctx || !list) {
450 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500451 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700452 }
453
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500454 /* reset Invalidator */
455 if(idleInvalidator)
456 idleInvalidator->markForSleep();
457
458 overlay::Overlay& ov = *ctx->mOverlay;
459 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700460
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700461 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
462 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700463 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700464 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700465
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500466 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700467 continue;
468 }
469
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500470 MdpPipeInfo& pipe_info =
471 sCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700472 int index = pipe_info.index;
473
474 if(index < 0) {
475 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500476 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700477 }
478
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500479 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700480
481 if (ctx ) {
482 private_handle_t *hnd = (private_handle_t *)layer->handle;
483 if(!hnd) {
484 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500485 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700486 }
487
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700488 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
489 using pipe: %d", __FUNCTION__, layer,
490 hnd, index );
491
492 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
493 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500494 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700495 }
496 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500497
498 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700499 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500500 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700501}
502
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500503/*
504 * Sets up BORDERFILL as default base pipe and detaches RGB0.
505 * Framebuffer is always updated using PLAY ioctl.
506 */
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700507
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500508bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
509
510 int fb_stride = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride;
511 int fb_width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
512 int fb_height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
513 int fb_fd = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd;
514
515 mdp_overlay ovInfo;
516 msmfb_overlay_data ovData;
517 memset(&ovInfo, 0, sizeof(mdp_overlay));
518 memset(&ovData, 0, sizeof(msmfb_overlay_data));
519
520 ovInfo.src.format = MDP_RGB_BORDERFILL;
521 ovInfo.src.width = fb_width;
522 ovInfo.src.height = fb_height;
523 ovInfo.src_rect.w = fb_width;
524 ovInfo.src_rect.h = fb_height;
525 ovInfo.dst_rect.w = fb_width;
526 ovInfo.dst_rect.h = fb_height;
527 ovInfo.id = MSMFB_NEW_REQUEST;
528
529 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
530 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
531 strerror(errno));
532 return false;
533 }
534
535 ovData.id = ovInfo.id;
536 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
537 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
538 strerror(errno));
539 return false;
540 }
541 return true;
542}
543
544bool MDPComp::init(hwc_context_t *ctx) {
545
546 if(!ctx) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700547 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
548 return false;
549 }
550
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500551 if(!setupBasePipe(ctx)) {
552 ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
553 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700554 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500555
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700556 char property[PROPERTY_VALUE_MAX];
557
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500558 sEnabled = false;
559 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
560 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
561 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
562 sEnabled = true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700563 }
564
565 sDebugLogs = false;
566 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
567 if(atoi(property) != 0)
568 sDebugLogs = true;
569 }
570
571 unsigned long idle_timeout = DEFAULT_IDLE_TIME;
572 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
573 if(atoi(property) != 0)
574 idle_timeout = atoi(property);
575 }
576
577 //create Idle Invalidator
578 idleInvalidator = IdleInvalidator::getInstance();
579
580 if(idleInvalidator == NULL) {
581 ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
582 } else {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500583 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700584 }
585 return true;
586}
587
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500588bool MDPComp::configure(hwc_context_t *ctx,
589 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700590
591 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500592 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700593 return false;
594 }
595
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500596 overlay::Overlay& ov = *ctx->mOverlay;
597
598 sActiveMax = ov.availablePipes();
599
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700600 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500601 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700602
603 if(doable) {
604 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500605 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700606 } else {
607 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
608 isMDPCompUsed = false;
609 }
610 } else {
611 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
612 doable);
613 isMDPCompUsed = false;
614 }
615
616 //Reset states
617 if(!isMDPCompUsed) {
618 //Reset current frame
619 reset(ctx, list);
620 }
621
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500622 sMDPCompState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700623
624 return isMDPCompUsed;
625}
626}; //namespace
627