blob: 4200be91a8df385dbc27356976b43985ebaac1e6 [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
Naseer Ahmed018e5452012-12-03 14:46:15 -0500276 if(ctx->listStats[HWC_DISPLAY_PRIMARY].needsAlphaScale) {
277 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
278 return false;
279 }
280
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700281 //FB composition on idle timeout
282 if(sIdleFallBack) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500283 sIdleFallBack = false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700284 ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
285 return false;
286 }
287
Saurabh Shah09549f62012-10-04 13:25:44 -0700288 //MDP composition is not efficient if layer needs rotator.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700289 for(int i = 0; i < numAppLayers; ++i) {
Saurabh Shah09549f62012-10-04 13:25:44 -0700290 // As MDP h/w supports flip operation, use MDP comp only for
291 // 180 transforms. Fail for any transform involving 90 (90, 270).
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500292 hwc_layer_1_t* layer = &list->hwLayers[i];
293 private_handle_t *hnd = (private_handle_t *)layer->handle;
294 if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
295 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
296 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700297 }
298 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700299 return true;
300}
301
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500302void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
303 hwc_display_contents_1_t* list) {
304 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700305
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500306 for(int index = 0 ; index < sCurrentFrame.count; index++ ) {
307 hwc_layer_1_t* layer = &(list->hwLayers[index]);
308 layerProp[index].mFlags |= HWC_MDPCOMP;
309 layer->compositionType = HWC_OVERLAY;
310 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700311 }
312}
313
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500314int MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type){
315 overlay::Overlay& ov = *ctx->mOverlay;
316 int mdp_pipe = -1;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700317
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500318 switch(type) {
319 case MDPCOMP_OV_ANY:
320 case MDPCOMP_OV_RGB:
321 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, HWC_DISPLAY_PRIMARY);
322 if(mdp_pipe != ovutils::OV_INVALID) {
323 return mdp_pipe;
324 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700325
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500326 if(type == MDPCOMP_OV_RGB) {
327 //Requested only for RGB pipe
328 return -1;
329 }
330 case MDPCOMP_OV_VG:
331 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, HWC_DISPLAY_PRIMARY);
332 if(mdp_pipe != ovutils::OV_INVALID) {
333 return mdp_pipe;
334 }
335 return -1;
336 default:
337 ALOGE("%s: Invalid pipe type",__FUNCTION__);
338 return -1;
339 };
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700340}
341
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500342bool MDPComp::allocLayerPipes(hwc_context_t *ctx,
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700343 hwc_display_contents_1_t* list,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500344 FrameInfo& currentFrame) {
345
346 overlay::Overlay& ov = *ctx->mOverlay;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700347
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700348 int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700349
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500350 currentFrame.count = layer_count;
351
352 currentFrame.pipeLayer = (PipeLayerPair*)
353 malloc(sizeof(PipeLayerPair) * currentFrame.count);
354
355 if(isYuvPresent(ctx)) {
356 int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex;
357 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
358 PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
359 MdpPipeInfo& pipe_info = info.pipeIndex;
360 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
361 if(pipe_info.index < 0) {
362 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
363 __FUNCTION__);
364 return false;
365 }
366 pipe_info.zOrder = nYuvIndex;
367 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700368
369 for(int index = 0 ; index < layer_count ; index++ ) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500370 if(index == ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex )
371 continue;
372
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700373 hwc_layer_1_t* layer = &list->hwLayers[index];
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500374 PipeLayerPair& info = currentFrame.pipeLayer[index];
375 MdpPipeInfo& pipe_info = info.pipeIndex;
376 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
377 if(pipe_info.index < 0) {
378 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
379 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700380 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500381 pipe_info.zOrder = index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700382 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700383 return true;
384}
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700385
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700386bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700387 int nPipeIndex, vsync_wait, isFG;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700388 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700389
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500390 FrameInfo &currentFrame = sCurrentFrame;
391 currentFrame.count = 0;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700392
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500393 if(currentFrame.pipeLayer) {
394 free(currentFrame.pipeLayer);
395 currentFrame.pipeLayer = NULL;
Naseer Ahmed52ca6d22012-10-08 14:03:01 -0400396 }
397
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700398 if(!ctx) {
399 ALOGE("%s: invalid context", __FUNCTION__);
400 return -1;
401 }
402
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500403 if(!allocLayerPipes(ctx, list, currentFrame)) {
404 //clean current frame data
405 currentFrame.count = 0;
406
407 if(currentFrame.pipeLayer) {
408 free(currentFrame.pipeLayer);
409 currentFrame.pipeLayer = NULL;
410 }
411
412 ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
413 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700414 }
415
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500416 for (int index = 0 ; index < currentFrame.count; index++) {
417 hwc_layer_1_t* layer = &list->hwLayers[index];
418 MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700419
420 if( prepare(ctx, layer, cur_pipe) != 0 ) {
421 ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
422 layer %d with pipe index:%d",__FUNCTION__,
423 index, cur_pipe.index);
424 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700425 }
426 }
427 return true;
428}
429
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500430void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
431 hwc_display_contents_1_t* list)
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700432{
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500433 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
434
Naseer Ahmeda2567482012-11-30 18:27:54 -0500435 for (int index = 0 ;
436 index < ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; index++) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500437 if(layerProp[index].mFlags & HWC_MDPCOMP) {
438 layerProp[index].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700439 }
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700440
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500441 if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
442 list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
Naseer Ahmedfb4cbdd2012-08-16 15:54:53 -0700443 }
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700444 }
445}
446
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500447bool MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700448
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500449 if(!isEnabled() || !isUsed()) {
450 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
451 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700452 }
453
454 if(!ctx || !list) {
455 ALOGE("%s: invalid contxt or list",__FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500456 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700457 }
458
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500459 /* reset Invalidator */
460 if(idleInvalidator)
461 idleInvalidator->markForSleep();
462
463 overlay::Overlay& ov = *ctx->mOverlay;
464 LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700465
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700466 int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
467 for(int i = 0; i < numHwLayers; i++ )
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700468 {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700469 hwc_layer_1_t *layer = &list->hwLayers[i];
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700470
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500471 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700472 continue;
473 }
474
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500475 MdpPipeInfo& pipe_info =
476 sCurrentFrame.pipeLayer[i].pipeIndex;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700477 int index = pipe_info.index;
478
479 if(index < 0) {
480 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500481 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700482 }
483
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500484 ovutils::eDest dest = (ovutils::eDest)index;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700485
486 if (ctx ) {
487 private_handle_t *hnd = (private_handle_t *)layer->handle;
488 if(!hnd) {
489 ALOGE("%s handle null", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500490 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700491 }
492
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700493 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
494 using pipe: %d", __FUNCTION__, layer,
495 hnd, index );
496
497 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
498 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500499 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700500 }
501 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500502
503 layerProp[i].mFlags &= ~HWC_MDPCOMP;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700504 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500505 return true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700506}
507
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500508/*
509 * Sets up BORDERFILL as default base pipe and detaches RGB0.
510 * Framebuffer is always updated using PLAY ioctl.
511 */
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700512
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500513bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
514
515 int fb_stride = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride;
516 int fb_width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
517 int fb_height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
518 int fb_fd = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd;
519
520 mdp_overlay ovInfo;
521 msmfb_overlay_data ovData;
522 memset(&ovInfo, 0, sizeof(mdp_overlay));
523 memset(&ovData, 0, sizeof(msmfb_overlay_data));
524
525 ovInfo.src.format = MDP_RGB_BORDERFILL;
526 ovInfo.src.width = fb_width;
527 ovInfo.src.height = fb_height;
528 ovInfo.src_rect.w = fb_width;
529 ovInfo.src_rect.h = fb_height;
530 ovInfo.dst_rect.w = fb_width;
531 ovInfo.dst_rect.h = fb_height;
532 ovInfo.id = MSMFB_NEW_REQUEST;
533
534 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
535 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
536 strerror(errno));
537 return false;
538 }
539
540 ovData.id = ovInfo.id;
541 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
542 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
543 strerror(errno));
544 return false;
545 }
546 return true;
547}
548
549bool MDPComp::init(hwc_context_t *ctx) {
550
551 if(!ctx) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700552 ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
553 return false;
554 }
555
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500556 if(!setupBasePipe(ctx)) {
557 ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
558 return false;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700559 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500560
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700561 char property[PROPERTY_VALUE_MAX];
562
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500563 sEnabled = false;
564 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
565 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
566 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
567 sEnabled = true;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700568 }
569
570 sDebugLogs = false;
571 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
572 if(atoi(property) != 0)
573 sDebugLogs = true;
574 }
575
576 unsigned long idle_timeout = DEFAULT_IDLE_TIME;
577 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
578 if(atoi(property) != 0)
579 idle_timeout = atoi(property);
580 }
581
582 //create Idle Invalidator
583 idleInvalidator = IdleInvalidator::getInstance();
584
585 if(idleInvalidator == NULL) {
586 ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
587 } else {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500588 idleInvalidator->init(timeout_handler, ctx, idle_timeout);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700589 }
590 return true;
591}
592
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500593bool MDPComp::configure(hwc_context_t *ctx,
594 hwc_display_contents_1_t* list) {
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700595
596 if(!isEnabled()) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500597 ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700598 return false;
599 }
600
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500601 overlay::Overlay& ov = *ctx->mOverlay;
602
603 sActiveMax = ov.availablePipes();
604
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700605 bool isMDPCompUsed = true;
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500606 bool doable = isDoable(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700607
608 if(doable) {
609 if(setup(ctx, list)) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500610 setMDPCompLayerFlags(ctx, list);
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700611 } else {
612 ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
613 isMDPCompUsed = false;
614 }
615 } else {
616 ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
617 doable);
618 isMDPCompUsed = false;
619 }
620
621 //Reset states
622 if(!isMDPCompUsed) {
623 //Reset current frame
624 reset(ctx, list);
625 }
626
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500627 sMDPCompState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700628
629 return isMDPCompUsed;
630}
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500631
632void MDPComp::dump(android::String8& buf)
633{
634 dumpsys_log(buf, " MDP Composition: ");
635 dumpsys_log(buf, "MDPCompState=%d\n", sMDPCompState);
636 //XXX: Log more info
637
638}
639
640
Naseer Ahmed7c958d42012-07-31 18:57:03 -0700641}; //namespace
642