blob: fcbbc2879d49820a85ee65e22c5b3cdd36ff61d3 [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
267 //Check for skip layers
268 if(isSkipPresent(ctx)) {
269 ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
Saurabh Shahb45b8812012-08-19 18:36:59 +0530270 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700271 }
272
273 //FB composition on idle timeout
274 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500275 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700276 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
277 return false;
278 }
279
Saurabh Shah09549f62012-10-04 13:25:44 -0700280 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700281 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700282 // As MDP h/w supports flip operation, use MDP comp only for
283 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500284 hwc_layer_1_t* layer = &list->hwLayers[i];
285 private_handle_t *hnd = (private_handle_t *)layer->handle;
286 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
287 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
288 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700289 }
290 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700291 return true;
292}
293
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500294void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
295 hwc_display_contents_1_t* list) {
296 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700297
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500298 for(int index = 0 ; index < sCurrentFrame.count; index++ ) {
299 hwc_layer_1_t* layer = &(list->hwLayers[index]);
300 layerProp[index].mFlags |= HWC_MDPCOMP;
301 layer->compositionType = HWC_OVERLAY;
302 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700303 }
304}
305
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500306int MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type){
307 overlay::Overlay& ov = *ctx->mOverlay;
308 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700309
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500310 switch(type) {
311 case MDPCOMP_OV_ANY:
312 case MDPCOMP_OV_RGB:
313 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, HWC_DISPLAY_PRIMARY);
314 if(mdp_pipe != ovutils::OV_INVALID) {
315 return mdp_pipe;
316 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700317
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500318 if(type == MDPCOMP_OV_RGB) {
319 //Requested only for RGB pipe
320 return -1;
321 }
322 case MDPCOMP_OV_VG:
323 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, HWC_DISPLAY_PRIMARY);
324 if(mdp_pipe != ovutils::OV_INVALID) {
325 return mdp_pipe;
326 }
327 return -1;
328 default:
329 ALOGE("%s: Invalid pipe type",__FUNCTION__);
330 return -1;
331 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700332}
333
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500334bool MDPComp::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700335 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500336 FrameInfo& currentFrame) {
337
338 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700339
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700340 int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700341
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500342 currentFrame.count = layer_count;
343
344 currentFrame.pipeLayer = (PipeLayerPair*)
345 malloc(sizeof(PipeLayerPair) * currentFrame.count);
346
347 if(isYuvPresent(ctx)) {
348 int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex;
349 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
350 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
351 MdpPipeInfo& pipe_info = info.pipeIndex;
352 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
353 if(pipe_info.index < 0) {
354 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
355 __FUNCTION__);
356 return false;
357 }
358 pipe_info.zOrder = nYuvIndex;
359 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700360
361 for(int index = 0 ; index < layer_count ; index++ ) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500362 if(index == ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex )
363 continue;
364
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700365 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500366 PipeLayerPair& info = currentFrame.pipeLayer[index];
367 MdpPipeInfo& pipe_info = info.pipeIndex;
368 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
369 if(pipe_info.index < 0) {
370 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
371 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700372 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500373 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700374 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700375 return true;
376}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700377
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700378bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700379 int nPipeIndex, vsync_wait, isFG;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700380 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700381
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500382 FrameInfo &currentFrame = sCurrentFrame;
383 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700384
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500385 if(currentFrame.pipeLayer) {
386 free(currentFrame.pipeLayer);
387 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400388 }
389
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700390 if(!ctx) {
391 ALOGE("%s: invalid context", __FUNCTION__);
392 return -1;
393 }
394
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500395 if(!allocLayerPipes(ctx, list, currentFrame)) {
396 //clean current frame data
397 currentFrame.count = 0;
398
399 if(currentFrame.pipeLayer) {
400 free(currentFrame.pipeLayer);
401 currentFrame.pipeLayer = NULL;
402 }
403
404 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
405 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700406 }
407
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500408 for (int index = 0 ; index < currentFrame.count; index++) {
409 hwc_layer_1_t* layer = &list->hwLayers[index];
410 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700411
412 if( prepare(ctx, layer, cur_pipe) != 0 ) {
413 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
414 layer %d with pipe index:%d",__FUNCTION__,
415 index, cur_pipe.index);
416 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700417 }
418 }
419 return true;
420}
421
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500422void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
423 hwc_display_contents_1_t* list)
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700424{
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500425 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
426
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700427 for (int index = 0 ; index < sCurrentFrame.count; index++) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500428 if(layerProp[index].mFlags & HWC_MDPCOMP) {
429 layerProp[index].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700430 }
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700431
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500432 if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
433 list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700434 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700435 }
436}
437
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500438bool MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700439
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500440 if(!isEnabled() || !isUsed()) {
441 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
442 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700443 }
444
445 if(!ctx || !list) {
446 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500447 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700448 }
449
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500450 /* reset Invalidator */
451 if(idleInvalidator)
452 idleInvalidator->markForSleep();
453
454 overlay::Overlay& ov = *ctx->mOverlay;
455 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700456
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700457 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
458 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700459 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700460 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700461
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500462 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700463 continue;
464 }
465
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500466 MdpPipeInfo& pipe_info =
467 sCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700468 int index = pipe_info.index;
469
470 if(index < 0) {
471 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500472 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700473 }
474
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500475 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700476
477 if (ctx ) {
478 private_handle_t *hnd = (private_handle_t *)layer->handle;
479 if(!hnd) {
480 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500481 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700482 }
483
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700484 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
485 using pipe: %d", __FUNCTION__, layer,
486 hnd, index );
487
488 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
489 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500490 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700491 }
492 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500493
494 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700495 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500496 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700497}
498
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500499/*
500 * Sets up BORDERFILL as default base pipe and detaches RGB0.
501 * Framebuffer is always updated using PLAY ioctl.
502 */
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700503
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500504bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
505
506 int fb_stride = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride;
507 int fb_width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
508 int fb_height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
509 int fb_fd = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd;
510
511 mdp_overlay ovInfo;
512 msmfb_overlay_data ovData;
513 memset(&ovInfo, 0, sizeof(mdp_overlay));
514 memset(&ovData, 0, sizeof(msmfb_overlay_data));
515
516 ovInfo.src.format = MDP_RGB_BORDERFILL;
517 ovInfo.src.width = fb_width;
518 ovInfo.src.height = fb_height;
519 ovInfo.src_rect.w = fb_width;
520 ovInfo.src_rect.h = fb_height;
521 ovInfo.dst_rect.w = fb_width;
522 ovInfo.dst_rect.h = fb_height;
523 ovInfo.id = MSMFB_NEW_REQUEST;
524
525 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
526 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
527 strerror(errno));
528 return false;
529 }
530
531 ovData.id = ovInfo.id;
532 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
533 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
534 strerror(errno));
535 return false;
536 }
537 return true;
538}
539
540bool MDPComp::init(hwc_context_t *ctx) {
541
542 if(!ctx) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700543 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
544 return false;
545 }
546
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500547 if(!setupBasePipe(ctx)) {
548 ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
549 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700550 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500551
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700552 char property[PROPERTY_VALUE_MAX];
553
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500554 sEnabled = false;
555 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
556 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
557 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
558 sEnabled = true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700559 }
560
561 sDebugLogs = false;
562 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
563 if(atoi(property) != 0)
564 sDebugLogs = true;
565 }
566
567 unsigned long idle_timeout = DEFAULT_IDLE_TIME;
568 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
569 if(atoi(property) != 0)
570 idle_timeout = atoi(property);
571 }
572
573 //create Idle Invalidator
574 idleInvalidator = IdleInvalidator::getInstance();
575
576 if(idleInvalidator == NULL) {
577 ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
578 } else {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500579 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700580 }
581 return true;
582}
583
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500584bool MDPComp::configure(hwc_context_t *ctx,
585 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700586
587 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500588 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700589 return false;
590 }
591
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500592 overlay::Overlay& ov = *ctx->mOverlay;
593
594 sActiveMax = ov.availablePipes();
595
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700596 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500597 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700598
599 if(doable) {
600 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500601 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700602 } else {
603 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
604 isMDPCompUsed = false;
605 }
606 } else {
607 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
608 doable);
609 isMDPCompUsed = false;
610 }
611
612 //Reset states
613 if(!isMDPCompUsed) {
614 //Reset current frame
615 reset(ctx, list);
616 }
617
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500618 sMDPCompState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700619
620 return isMDPCompUsed;
621}
622}; //namespace
623