blob: 3bca539f7a889754bad777ba7906b8c21dd8981b [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
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500267 if(isSecuring(ctx)) {
268 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
269 return false;
270 }
271
Naseer Ahmed76e313c2012-12-01 18:12:59 -0500272 if(ctx->mSecureMode)
273 return false;
274
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500275 //Check for skip layers
276 if(isSkipPresent(ctx)) {
277 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530278 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700279 }
280
Naseer Ahmed018e5452012-12-03 14:46:15 -0500281 if(ctx->listStats[HWC_DISPLAY_PRIMARY].needsAlphaScale) {
282 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
283 return false;
284 }
285
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700286 //FB composition on idle timeout
287 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500288 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700289 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
290 return false;
291 }
292
Saurabh Shah09549f62012-10-04 13:25:44 -0700293 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700294 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700295 // As MDP h/w supports flip operation, use MDP comp only for
296 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500297 hwc_layer_1_t* layer = &list->hwLayers[i];
298 private_handle_t *hnd = (private_handle_t *)layer->handle;
299 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
300 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
301 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700302 }
303 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700304 return true;
305}
306
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500307void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
308 hwc_display_contents_1_t* list) {
309 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700310
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500311 for(int index = 0 ; index < sCurrentFrame.count; index++ ) {
312 hwc_layer_1_t* layer = &(list->hwLayers[index]);
313 layerProp[index].mFlags |= HWC_MDPCOMP;
314 layer->compositionType = HWC_OVERLAY;
315 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700316 }
317}
318
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500319int MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type){
320 overlay::Overlay& ov = *ctx->mOverlay;
321 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700322
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500323 switch(type) {
324 case MDPCOMP_OV_ANY:
325 case MDPCOMP_OV_RGB:
326 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, HWC_DISPLAY_PRIMARY);
327 if(mdp_pipe != ovutils::OV_INVALID) {
328 return mdp_pipe;
329 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700330
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500331 if(type == MDPCOMP_OV_RGB) {
332 //Requested only for RGB pipe
333 return -1;
334 }
335 case MDPCOMP_OV_VG:
336 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, HWC_DISPLAY_PRIMARY);
337 if(mdp_pipe != ovutils::OV_INVALID) {
338 return mdp_pipe;
339 }
340 return -1;
341 default:
342 ALOGE("%s: Invalid pipe type",__FUNCTION__);
343 return -1;
344 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700345}
346
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500347bool MDPComp::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700348 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500349 FrameInfo& currentFrame) {
350
351 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700352
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700353 int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700354
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500355 currentFrame.count = layer_count;
356
357 currentFrame.pipeLayer = (PipeLayerPair*)
358 malloc(sizeof(PipeLayerPair) * currentFrame.count);
359
360 if(isYuvPresent(ctx)) {
361 int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex;
362 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
363 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
364 MdpPipeInfo& pipe_info = info.pipeIndex;
365 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
366 if(pipe_info.index < 0) {
367 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
368 __FUNCTION__);
369 return false;
370 }
371 pipe_info.zOrder = nYuvIndex;
372 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700373
374 for(int index = 0 ; index < layer_count ; index++ ) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500375 if(index == ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex )
376 continue;
377
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700378 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500379 PipeLayerPair& info = currentFrame.pipeLayer[index];
380 MdpPipeInfo& pipe_info = info.pipeIndex;
381 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
382 if(pipe_info.index < 0) {
383 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
384 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700385 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500386 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700387 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700388 return true;
389}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700390
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700391bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700392 int nPipeIndex, vsync_wait, isFG;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700393 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700394
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500395 FrameInfo &currentFrame = sCurrentFrame;
396 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700397
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500398 if(currentFrame.pipeLayer) {
399 free(currentFrame.pipeLayer);
400 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400401 }
402
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700403 if(!ctx) {
404 ALOGE("%s: invalid context", __FUNCTION__);
405 return -1;
406 }
407
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500408 if(!allocLayerPipes(ctx, list, currentFrame)) {
409 //clean current frame data
410 currentFrame.count = 0;
411
412 if(currentFrame.pipeLayer) {
413 free(currentFrame.pipeLayer);
414 currentFrame.pipeLayer = NULL;
415 }
416
417 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
418 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700419 }
420
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500421 for (int index = 0 ; index < currentFrame.count; index++) {
422 hwc_layer_1_t* layer = &list->hwLayers[index];
423 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700424
425 if( prepare(ctx, layer, cur_pipe) != 0 ) {
426 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
427 layer %d with pipe index:%d",__FUNCTION__,
428 index, cur_pipe.index);
429 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700430 }
431 }
432 return true;
433}
434
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500435void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
436 hwc_display_contents_1_t* list)
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700437{
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500438 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
439
Naseer Ahmeda2567482012-11-30 18:27:54 -0500440 for (int index = 0 ;
441 index < ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; index++) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500442 if(layerProp[index].mFlags & HWC_MDPCOMP) {
443 layerProp[index].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700444 }
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700445
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500446 if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
447 list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700448 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700449 }
450}
451
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500452bool MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700453
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500454 if(!isEnabled() || !isUsed()) {
455 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
456 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700457 }
458
459 if(!ctx || !list) {
460 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500461 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700462 }
463
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500464 /* reset Invalidator */
465 if(idleInvalidator)
466 idleInvalidator->markForSleep();
467
468 overlay::Overlay& ov = *ctx->mOverlay;
469 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700470
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700471 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
472 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700473 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700474 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700475
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500476 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700477 continue;
478 }
479
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500480 MdpPipeInfo& pipe_info =
481 sCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700482 int index = pipe_info.index;
483
484 if(index < 0) {
485 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500486 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700487 }
488
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500489 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700490
491 if (ctx ) {
492 private_handle_t *hnd = (private_handle_t *)layer->handle;
493 if(!hnd) {
494 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500495 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700496 }
497
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700498 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
499 using pipe: %d", __FUNCTION__, layer,
500 hnd, index );
501
502 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
503 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500504 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700505 }
506 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500507
508 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700509 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500510 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700511}
512
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500513/*
514 * Sets up BORDERFILL as default base pipe and detaches RGB0.
515 * Framebuffer is always updated using PLAY ioctl.
516 */
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700517
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500518bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
519
520 int fb_stride = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride;
521 int fb_width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
522 int fb_height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
523 int fb_fd = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd;
524
525 mdp_overlay ovInfo;
526 msmfb_overlay_data ovData;
527 memset(&ovInfo, 0, sizeof(mdp_overlay));
528 memset(&ovData, 0, sizeof(msmfb_overlay_data));
529
530 ovInfo.src.format = MDP_RGB_BORDERFILL;
531 ovInfo.src.width = fb_width;
532 ovInfo.src.height = fb_height;
533 ovInfo.src_rect.w = fb_width;
534 ovInfo.src_rect.h = fb_height;
535 ovInfo.dst_rect.w = fb_width;
536 ovInfo.dst_rect.h = fb_height;
537 ovInfo.id = MSMFB_NEW_REQUEST;
538
539 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
540 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
541 strerror(errno));
542 return false;
543 }
544
545 ovData.id = ovInfo.id;
546 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
547 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
548 strerror(errno));
549 return false;
550 }
551 return true;
552}
553
554bool MDPComp::init(hwc_context_t *ctx) {
555
556 if(!ctx) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700557 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
558 return false;
559 }
560
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500561 if(!setupBasePipe(ctx)) {
562 ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
563 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700564 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500565
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700566 char property[PROPERTY_VALUE_MAX];
567
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500568 sEnabled = false;
569 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
570 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
571 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
572 sEnabled = true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700573 }
574
575 sDebugLogs = false;
576 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
577 if(atoi(property) != 0)
578 sDebugLogs = true;
579 }
580
581 unsigned long idle_timeout = DEFAULT_IDLE_TIME;
582 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
583 if(atoi(property) != 0)
584 idle_timeout = atoi(property);
585 }
586
587 //create Idle Invalidator
588 idleInvalidator = IdleInvalidator::getInstance();
589
590 if(idleInvalidator == NULL) {
591 ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
592 } else {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500593 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700594 }
595 return true;
596}
597
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500598bool MDPComp::configure(hwc_context_t *ctx,
599 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700600
601 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500602 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700603 return false;
604 }
605
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500606 overlay::Overlay& ov = *ctx->mOverlay;
607
608 sActiveMax = ov.availablePipes();
609
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700610 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500611 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700612
613 if(doable) {
614 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500615 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700616 } else {
617 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
618 isMDPCompUsed = false;
619 }
620 } else {
621 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
622 doable);
623 isMDPCompUsed = false;
624 }
625
626 //Reset states
627 if(!isMDPCompUsed) {
628 //Reset current frame
629 reset(ctx, list);
630 }
631
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500632 sMDPCompState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700633
634 return isMDPCompUsed;
635}
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500636
637void MDPComp::dump(android::String8& buf)
638{
639 dumpsys_log(buf, " MDP Composition: ");
640 dumpsys_log(buf, "MDPCompState=%d\n", sMDPCompState);
641 //XXX: Log more info
642
643}
644
645
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700646}; //namespace
647