blob: a3d7b283a841cf6c222bc39d3a8f9307667afa9d [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/****** Class MDPComp ***********/
28
Naseer Ahmed54821fe2012-11-28 18:44:38 -050029MDPComp::eState MDPComp::sMDPCompState = MDPCOMP_OFF;
30struct MDPComp::FrameInfo MDPComp::sCurrentFrame;
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;
35int MDPComp::sActiveMax = 0;
36bool MDPComp::sSecuredVid = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -070037
38bool MDPComp::deinit() {
39 //XXX: Tear down MDP comp state
40 return true;
41}
Naseer Ahmed54821fe2012-11-28 18:44:38 -050042bool MDPComp::isSkipPresent (hwc_context_t *ctx) {
43 return ctx->listStats[HWC_DISPLAY_PRIMARY].skipCount;
44};
45
46bool MDPComp::isYuvPresent (hwc_context_t *ctx) {
47 return ctx->listStats[HWC_DISPLAY_PRIMARY].yuvCount;
48};
Naseer Ahmed7c958d42012-07-31 18:57:03 -070049
50void MDPComp::timeout_handler(void *udata) {
51 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
52
53 if(!ctx) {
54 ALOGE("%s: received empty data in timer callback", __FUNCTION__);
55 return;
56 }
57
Jesse Hall3be78d92012-08-21 15:12:23 -070058 if(!ctx->proc) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -070059 ALOGE("%s: HWC proc not registered", __FUNCTION__);
60 return;
61 }
62 sIdleFallBack = true;
63 /* Trigger SF to redraw the current frame */
Jesse Hall3be78d92012-08-21 15:12:23 -070064 ctx->proc->invalidate(ctx->proc);
Naseer Ahmed7c958d42012-07-31 18:57:03 -070065}
66
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -070067void MDPComp::reset(hwc_context_t *ctx, hwc_display_contents_1_t* list ) {
68 //Reset flags and states
69 unsetMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -070070 sCurrentFrame.count = 0;
Naseer Ahmed54821fe2012-11-28 18:44:38 -050071 if(sCurrentFrame.pipeLayer) {
72 free(sCurrentFrame.pipeLayer);
73 sCurrentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -040074 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -070075}
76
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070077void MDPComp::print_info(hwc_layer_1_t* layer)
Naseer Ahmed7c958d42012-07-31 18:57:03 -070078{
79 hwc_rect_t sourceCrop = layer->sourceCrop;
80 hwc_rect_t displayFrame = layer->displayFrame;
81
82 int s_l = sourceCrop.left;
83 int s_t = sourceCrop.top;
84 int s_r = sourceCrop.right;
85 int s_b = sourceCrop.bottom;
86
87 int d_l = displayFrame.left;
88 int d_t = displayFrame.top;
89 int d_r = displayFrame.right;
90 int d_b = displayFrame.bottom;
91
92 ALOGD_IF(isDebug(), "src:[%d,%d,%d,%d] (%d x %d) \
93 dst:[%d,%d,%d,%d] (%d x %d)",
94 s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
95 d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
96}
Naseer Ahmed54821fe2012-11-28 18:44:38 -050097
98void MDPComp::setVidInfo(hwc_layer_1_t *layer, ovutils::eMdpFlags &mdpFlags) {
99 private_handle_t *hnd = (private_handle_t *)layer->handle;
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800100 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500101
102 if(isSecureBuffer(hnd)) {
103 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
104 sSecuredVid = true;
105 }
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800106 if((metadata->operation & PP_PARAM_INTERLACED) && metadata->interlaced) {
107 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
108 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500109}
110
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700111/*
112 * Configures pipe(s) for MDP composition
113 */
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700114int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500115 MdpPipeInfo& mdp_info) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700116
117 int nPipeIndex = mdp_info.index;
118
119 if (ctx) {
120
121 private_handle_t *hnd = (private_handle_t *)layer->handle;
122
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500123 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700124
125 if(!hnd) {
126 ALOGE("%s: layer handle is NULL", __FUNCTION__);
127 return -1;
128 }
129
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500130 int hw_w = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
131 int hw_h = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700132
133 hwc_rect_t sourceCrop = layer->sourceCrop;
134 hwc_rect_t displayFrame = layer->displayFrame;
135
136 const int src_w = sourceCrop.right - sourceCrop.left;
137 const int src_h = sourceCrop.bottom - sourceCrop.top;
138
139 hwc_rect_t crop = sourceCrop;
140 int crop_w = crop.right - crop.left;
141 int crop_h = crop.bottom - crop.top;
142
143 hwc_rect_t dst = displayFrame;
144 int dst_w = dst.right - dst.left;
145 int dst_h = dst.bottom - dst.top;
146
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700147 if(dst.left < 0 || dst.top < 0 ||
148 dst.right > hw_w || dst.bottom > hw_h) {
149 ALOGD_IF(isDebug(),"%s: Destination has negative coordinates",
150 __FUNCTION__);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700151 qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, 0);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700152
153 //Update calulated width and height
154 crop_w = crop.right - crop.left;
155 crop_h = crop.bottom - crop.top;
156
157 dst_w = dst.right - dst.left;
158 dst_h = dst.bottom - dst.top;
159 }
160
161 if( (dst_w > hw_w)|| (dst_h > hw_h)) {
162 ALOGD_IF(isDebug(),"%s: Dest rect exceeds FB", __FUNCTION__);
163 print_info(layer);
164 dst_w = hw_w;
165 dst_h = hw_h;
166 }
167
168 // Determine pipe to set based on pipe index
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500169 ovutils::eDest dest = (ovutils::eDest)mdp_info.index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700170
171 ovutils::eZorder zOrder = ovutils::ZORDER_0;
172
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500173 if(mdp_info.zOrder == 0 ) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700174 zOrder = ovutils::ZORDER_0;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500175 } else if(mdp_info.zOrder == 1 ) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700176 zOrder = ovutils::ZORDER_1;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500177 } else if(mdp_info.zOrder == 2 ) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700178 zOrder = ovutils::ZORDER_2;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500179 } else if(mdp_info.zOrder == 3) {
180 zOrder = ovutils::ZORDER_3;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700181 }
182
183 // Order order order
184 // setSource - just setting source
185 // setParameter - changes src w/h/f accordingly
186 // setCrop - ROI - src_rect
187 // setPosition - dst_rect
188 // commit - commit changes to mdp driver
189 // queueBuffer - not here, happens when draw is called
190
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700191 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500192
193 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
194
195 if(isYuvBuffer(hnd))
196 setVidInfo(layer, mdpFlags);
197
Saurabh Shah799a3972012-09-01 12:16:12 -0700198 ovutils::setMdpFlags(mdpFlags,ovutils::OV_MDP_BACKEND_COMPOSITION);
Saurabh Shah91a6a992012-08-20 15:25:28 -0700199
200 if(layer->blending == HWC_BLENDING_PREMULT) {
201 ovutils::setMdpFlags(mdpFlags,
202 ovutils::OV_MDP_BLEND_FG_PREMULT);
203 }
204
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500205 ovutils::eTransform orient = overlay::utils::OVERLAY_TRANSFORM_0 ;
Saurabh Shah09549f62012-10-04 13:25:44 -0700206
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500207 if(!(layer->transform & HWC_TRANSFORM_ROT_90)) {
208 if(layer->transform & HWC_TRANSFORM_FLIP_H) {
209 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
210 }
Saurabh Shah09549f62012-10-04 13:25:44 -0700211
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500212 if(layer->transform & HWC_TRANSFORM_FLIP_V) {
213 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
214 }
215 } else {
216 orient = static_cast<ovutils::eTransform>(layer->transform);
217 }
Saurabh Shah09549f62012-10-04 13:25:44 -0700218
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700219 ovutils::PipeArgs parg(mdpFlags,
220 info,
221 zOrder,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500222 ovutils::IS_FG_OFF,
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700223 ovutils::ROT_FLAG_DISABLED);
224
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500225 ov.setSource(parg, dest);
226
227 ov.setTransform(orient, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700228
229 ovutils::Dim dcrop(crop.left, crop.top, crop_w, crop_h);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500230 ov.setCrop(dcrop, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700231
232 ovutils::Dim dim(dst.left, dst.top, dst_w, dst_h);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500233 ov.setPosition(dim, dest);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700234
235 ALOGD_IF(isDebug(),"%s: MDP set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] \
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500236 nPipe: %d zorder: %d",__FUNCTION__, dcrop.x,
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700237 dcrop.y,dcrop.w, dcrop.h, dim.x, dim.y, dim.w, dim.h,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500238 mdp_info.index, mdp_info.zOrder);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700239
240 if (!ov.commit(dest)) {
241 ALOGE("%s: commit failed", __FUNCTION__);
242 return -1;
243 }
244 }
245 return 0;
246}
247
248/*
249 * MDPComp not possible when
250 * 1. We have more than sMaxLayers
251 * 2. External display connected
252 * 3. Composition is triggered by
253 * Idle timer expiry
254 * 4. Rotation is needed
255 * 5. Overlay in use
256 */
257
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500258bool MDPComp::isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700259 //Number of layers
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700260 int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500261
262 if(numAppLayers < 1 || numAppLayers > (uint32_t)sActiveMax) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700263 ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
264 return false;
265 }
266
Amara Venkata Mastan Manoj Kumar75526f52012-12-27 18:27:01 -0800267 if(ctx->mExtDispConfiguring) {
268 ALOGD_IF( isDebug(),"%s: External Display connection is pending",
269 __FUNCTION__);
270 return false;
271 }
272
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500273 if(isSecuring(ctx)) {
274 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
275 return false;
276 }
277
Naseer Ahmed76e313c2012-12-01 18:12:59 -0500278 if(ctx->mSecureMode)
279 return false;
280
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500281 //Check for skip layers
282 if(isSkipPresent(ctx)) {
283 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530284 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700285 }
286
Naseer Ahmed018e5452012-12-03 14:46:15 -0500287 if(ctx->listStats[HWC_DISPLAY_PRIMARY].needsAlphaScale) {
288 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
289 return false;
290 }
291
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700292 //FB composition on idle timeout
293 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500294 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700295 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
296 return false;
297 }
298
Saurabh Shah09549f62012-10-04 13:25:44 -0700299 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700300 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700301 // As MDP h/w supports flip operation, use MDP comp only for
302 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500303 hwc_layer_1_t* layer = &list->hwLayers[i];
304 private_handle_t *hnd = (private_handle_t *)layer->handle;
305 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
306 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
307 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700308 }
309 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700310 return true;
311}
312
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500313void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
314 hwc_display_contents_1_t* list) {
315 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700316
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500317 for(int index = 0 ; index < sCurrentFrame.count; index++ ) {
318 hwc_layer_1_t* layer = &(list->hwLayers[index]);
319 layerProp[index].mFlags |= HWC_MDPCOMP;
320 layer->compositionType = HWC_OVERLAY;
321 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700322 }
323}
324
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500325int MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type){
326 overlay::Overlay& ov = *ctx->mOverlay;
327 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700328
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500329 switch(type) {
330 case MDPCOMP_OV_ANY:
331 case MDPCOMP_OV_RGB:
332 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, HWC_DISPLAY_PRIMARY);
333 if(mdp_pipe != ovutils::OV_INVALID) {
334 return mdp_pipe;
335 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700336
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500337 if(type == MDPCOMP_OV_RGB) {
338 //Requested only for RGB pipe
339 return -1;
340 }
341 case MDPCOMP_OV_VG:
342 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, HWC_DISPLAY_PRIMARY);
343 if(mdp_pipe != ovutils::OV_INVALID) {
344 return mdp_pipe;
345 }
346 return -1;
347 default:
348 ALOGE("%s: Invalid pipe type",__FUNCTION__);
349 return -1;
350 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700351}
352
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500353bool MDPComp::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700354 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500355 FrameInfo& currentFrame) {
356
357 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700358
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700359 int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700360
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500361 currentFrame.count = layer_count;
362
363 currentFrame.pipeLayer = (PipeLayerPair*)
364 malloc(sizeof(PipeLayerPair) * currentFrame.count);
365
366 if(isYuvPresent(ctx)) {
367 int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex;
368 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
369 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
370 MdpPipeInfo& pipe_info = info.pipeIndex;
371 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
372 if(pipe_info.index < 0) {
373 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
374 __FUNCTION__);
375 return false;
376 }
377 pipe_info.zOrder = nYuvIndex;
378 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700379
380 for(int index = 0 ; index < layer_count ; index++ ) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500381 if(index == ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex )
382 continue;
383
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700384 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500385 PipeLayerPair& info = currentFrame.pipeLayer[index];
386 MdpPipeInfo& pipe_info = info.pipeIndex;
387 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
388 if(pipe_info.index < 0) {
389 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
390 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700391 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500392 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700393 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700394 return true;
395}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700396
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700397bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700398 int nPipeIndex, vsync_wait, isFG;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700399 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700400
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500401 FrameInfo &currentFrame = sCurrentFrame;
402 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700403
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500404 if(currentFrame.pipeLayer) {
405 free(currentFrame.pipeLayer);
406 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400407 }
408
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700409 if(!ctx) {
410 ALOGE("%s: invalid context", __FUNCTION__);
411 return -1;
412 }
413
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500414 if(!allocLayerPipes(ctx, list, currentFrame)) {
415 //clean current frame data
416 currentFrame.count = 0;
417
418 if(currentFrame.pipeLayer) {
419 free(currentFrame.pipeLayer);
420 currentFrame.pipeLayer = NULL;
421 }
422
423 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
424 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700425 }
426
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500427 for (int index = 0 ; index < currentFrame.count; index++) {
428 hwc_layer_1_t* layer = &list->hwLayers[index];
429 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700430
431 if( prepare(ctx, layer, cur_pipe) != 0 ) {
432 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
433 layer %d with pipe index:%d",__FUNCTION__,
434 index, cur_pipe.index);
435 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700436 }
437 }
438 return true;
439}
440
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500441void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
442 hwc_display_contents_1_t* list)
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700443{
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500444 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
445
Naseer Ahmeda2567482012-11-30 18:27:54 -0500446 for (int index = 0 ;
447 index < ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; index++) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500448 if(layerProp[index].mFlags & HWC_MDPCOMP) {
449 layerProp[index].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700450 }
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700451
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500452 if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
453 list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700454 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700455 }
456}
457
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500458bool MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700459
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500460 if(!isEnabled() || !isUsed()) {
461 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
462 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700463 }
464
465 if(!ctx || !list) {
466 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500467 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700468 }
469
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500470 /* reset Invalidator */
471 if(idleInvalidator)
472 idleInvalidator->markForSleep();
473
474 overlay::Overlay& ov = *ctx->mOverlay;
475 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700476
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700477 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
478 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700479 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700480 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700481
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500482 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700483 continue;
484 }
485
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500486 MdpPipeInfo& pipe_info =
487 sCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700488 int index = pipe_info.index;
489
490 if(index < 0) {
491 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500492 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700493 }
494
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500495 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700496
497 if (ctx ) {
498 private_handle_t *hnd = (private_handle_t *)layer->handle;
499 if(!hnd) {
500 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500501 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700502 }
503
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700504 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
505 using pipe: %d", __FUNCTION__, layer,
506 hnd, index );
507
508 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
509 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500510 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700511 }
512 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500513
514 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700515 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500516 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700517}
518
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500519/*
520 * Sets up BORDERFILL as default base pipe and detaches RGB0.
521 * Framebuffer is always updated using PLAY ioctl.
522 */
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700523
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500524bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
525
526 int fb_stride = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride;
527 int fb_width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
528 int fb_height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
529 int fb_fd = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd;
530
531 mdp_overlay ovInfo;
532 msmfb_overlay_data ovData;
533 memset(&ovInfo, 0, sizeof(mdp_overlay));
534 memset(&ovData, 0, sizeof(msmfb_overlay_data));
535
536 ovInfo.src.format = MDP_RGB_BORDERFILL;
537 ovInfo.src.width = fb_width;
538 ovInfo.src.height = fb_height;
539 ovInfo.src_rect.w = fb_width;
540 ovInfo.src_rect.h = fb_height;
541 ovInfo.dst_rect.w = fb_width;
542 ovInfo.dst_rect.h = fb_height;
543 ovInfo.id = MSMFB_NEW_REQUEST;
544
545 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
546 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
547 strerror(errno));
548 return false;
549 }
550
551 ovData.id = ovInfo.id;
552 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
553 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
554 strerror(errno));
555 return false;
556 }
557 return true;
558}
559
560bool MDPComp::init(hwc_context_t *ctx) {
561
562 if(!ctx) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700563 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
564 return false;
565 }
566
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500567 if(!setupBasePipe(ctx)) {
568 ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
569 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700570 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500571
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700572 char property[PROPERTY_VALUE_MAX];
573
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500574 sEnabled = false;
575 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
576 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
577 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
578 sEnabled = true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700579 }
580
581 sDebugLogs = false;
582 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
583 if(atoi(property) != 0)
584 sDebugLogs = true;
585 }
586
587 unsigned long idle_timeout = DEFAULT_IDLE_TIME;
588 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
589 if(atoi(property) != 0)
590 idle_timeout = atoi(property);
591 }
592
593 //create Idle Invalidator
594 idleInvalidator = IdleInvalidator::getInstance();
595
596 if(idleInvalidator == NULL) {
597 ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
598 } else {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500599 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700600 }
601 return true;
602}
603
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500604bool MDPComp::configure(hwc_context_t *ctx,
605 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700606
607 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500608 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700609 return false;
610 }
611
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500612 overlay::Overlay& ov = *ctx->mOverlay;
613
614 sActiveMax = ov.availablePipes();
615
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700616 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500617 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700618
619 if(doable) {
620 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500621 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700622 } else {
623 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
624 isMDPCompUsed = false;
625 }
626 } else {
627 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
628 doable);
629 isMDPCompUsed = false;
630 }
631
632 //Reset states
633 if(!isMDPCompUsed) {
634 //Reset current frame
635 reset(ctx, list);
636 }
637
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500638 sMDPCompState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700639
640 return isMDPCompUsed;
641}
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500642
643void MDPComp::dump(android::String8& buf)
644{
645 dumpsys_log(buf, " MDP Composition: ");
646 dumpsys_log(buf, "MDPCompState=%d\n", sMDPCompState);
647 //XXX: Log more info
648
649}
650
651
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700652}; //namespace
653