Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2008 The Android Open Source Project |
| 3 | * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved. |
| 4 | * |
| 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
| 8 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * |
| 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
| 16 | */ |
| 17 | |
| 18 | #include "overlayUtils.h" |
| 19 | #include "overlayMdp.h" |
| 20 | |
| 21 | #undef ALOG_TAG |
| 22 | #define ALOG_TAG "overlay" |
| 23 | |
| 24 | namespace ovutils = overlay::utils; |
| 25 | namespace overlay { |
| 26 | bool MdpCtrl::open(uint32_t fbnum) { |
| 27 | // FD open |
| 28 | if(!utils::openDev(mFd, fbnum, |
| 29 | Res::devTemplate, O_RDWR)){ |
| 30 | ALOGE("Ctrl failed to open fbnum=%d", fbnum); |
| 31 | return false; |
| 32 | } |
| 33 | return true; |
| 34 | } |
| 35 | |
| 36 | void MdpCtrl::reset() { |
| 37 | utils::memset0(mOVInfo); |
| 38 | utils::memset0(mLkgo); |
| 39 | mOVInfo.id = -1; |
| 40 | mLkgo.id = -1; |
| 41 | } |
| 42 | |
| 43 | bool MdpCtrl::close() { |
| 44 | if(-1 == static_cast<int>(mOVInfo.id)) return true; |
| 45 | if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) { |
| 46 | ALOGE("MdpCtrl close error in unset"); |
| 47 | return false; |
| 48 | } |
| 49 | reset(); |
| 50 | if(!mFd.close()) { |
| 51 | return false; |
| 52 | } |
| 53 | return true; |
| 54 | } |
| 55 | |
| 56 | bool MdpCtrl::getScreenInfo(overlay::utils::ScreenInfo& info) { |
| 57 | fb_fix_screeninfo finfo; |
| 58 | if (!mdp_wrapper::getFScreenInfo(mFd.getFD(), finfo)) { |
| 59 | return false; |
| 60 | } |
| 61 | |
| 62 | fb_var_screeninfo vinfo; |
| 63 | if (!mdp_wrapper::getVScreenInfo(mFd.getFD(), vinfo)) { |
| 64 | return false; |
| 65 | } |
| 66 | info.mFBWidth = vinfo.xres; |
| 67 | info.mFBHeight = vinfo.yres; |
| 68 | info.mFBbpp = vinfo.bits_per_pixel; |
| 69 | info.mFBystride = finfo.line_length; |
| 70 | return true; |
| 71 | } |
| 72 | |
| 73 | bool MdpCtrl::get() { |
| 74 | mdp_overlay ov; |
| 75 | ov.id = mOVInfo.id; |
| 76 | if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) { |
| 77 | ALOGE("MdpCtrl get failed"); |
| 78 | return false; |
| 79 | } |
| 80 | mOVInfo = ov; |
| 81 | return true; |
| 82 | } |
| 83 | |
| 84 | // that is the second part of original setParameter function |
| 85 | void MdpCtrl::setSrcFormat(const utils::Whf& whf) { |
| 86 | |
| 87 | //By default mdp src format is the same as buffer's |
| 88 | mOVInfo.src.format = whf.format; |
| 89 | |
| 90 | //If rotation is used and input formats are tiled then output of rotator is |
| 91 | //non-tiled. |
| 92 | // FIXME mRotInfo.enable = 1; for enable |
| 93 | if (getUserData()) { // if rotations enabled in MdpCtrl |
| 94 | if (whf.format == MDP_Y_CRCB_H2V2_TILE) |
| 95 | mOVInfo.src.format = MDP_Y_CRCB_H2V2; |
| 96 | else if (whf.format == MDP_Y_CBCR_H2V2_TILE) |
| 97 | mOVInfo.src.format = MDP_Y_CBCR_H2V2; |
| 98 | return; |
| 99 | } |
| 100 | |
| 101 | } |
| 102 | |
| 103 | bool MdpCtrl::set() { |
| 104 | if(!this->ovChanged()) { |
| 105 | return true; // nothing todo here. |
| 106 | } |
| 107 | |
| 108 | if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) { |
| 109 | ALOGE("MdpCtrl failed to setOverlay, restoring last known " |
| 110 | "good ov info"); |
| 111 | mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo); |
| 112 | mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo); |
| 113 | this->restore(); |
| 114 | // FIXME, do we need to set the old one? |
| 115 | return false; |
| 116 | } |
| 117 | this->save(); |
| 118 | return true; |
| 119 | } |
| 120 | |
| 121 | bool MdpCtrl::setPosition(const overlay::utils::Dim& d, |
| 122 | int fbw, int fbh) |
| 123 | { |
| 124 | // Validatee against FB size |
| 125 | if(!d.check(fbw, fbh)) { |
| 126 | ALOGE("MdpCtrl setPosition failed dest dim violate screen limits"); |
| 127 | return false; |
| 128 | } |
| 129 | |
| 130 | ovutils::Dim dim(d); |
| 131 | ovutils::Dim ovsrcdim = getSrcRectDim(); |
| 132 | // Scaling of upto a max of 8 times supported |
| 133 | if(dim.w >(ovsrcdim.w * ovutils::HW_OV_MAGNIFICATION_LIMIT)){ |
| 134 | dim.w = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.w; |
| 135 | dim.x = (fbw - dim.w) / 2; |
| 136 | } |
| 137 | if(dim.h >(ovsrcdim.h * ovutils::HW_OV_MAGNIFICATION_LIMIT)) { |
| 138 | dim.h = ovutils::HW_OV_MAGNIFICATION_LIMIT * ovsrcdim.h; |
| 139 | dim.y = (fbh - dim.h) / 2; |
| 140 | } |
| 141 | |
| 142 | //dim.even_out(); |
| 143 | setDstRectDim(dim); |
| 144 | return true; |
| 145 | } |
| 146 | |
| 147 | void MdpCtrl::updateSource(RotatorBase* r, |
| 148 | const utils::PipeArgs& args, |
| 149 | const utils::ScreenInfo& info) { |
| 150 | utils::Whf whf(args.whf); |
| 151 | mOVInfo.src.width = whf.w; |
| 152 | mOVInfo.src.height = whf.h; |
| 153 | mOVInfo.src_rect.x = 0; |
| 154 | mOVInfo.src_rect.y = 0; |
| 155 | mOVInfo.dst_rect.x = 0; |
| 156 | mOVInfo.dst_rect.y = 0; |
| 157 | mOVInfo.dst_rect.w = whf.w; |
| 158 | mOVInfo.dst_rect.h = whf.h; |
| 159 | mOVInfo.src.format = whf.format; |
| 160 | |
| 161 | if(whf.format == MDP_Y_CRCB_H2V2_TILE || |
| 162 | (whf.format == MDP_Y_CBCR_H2V2_TILE)) { |
| 163 | // passing by value, setInfo fills it and return by val |
| 164 | mOVInfo = r->setInfo(args, mOVInfo); |
| 165 | } else { |
| 166 | mOVInfo.src_rect.w = whf.w; |
| 167 | mOVInfo.src_rect.h = whf.h; |
| 168 | } |
| 169 | |
| 170 | if (whf.w > info.mFBWidth) |
| 171 | mOVInfo.dst_rect.w = info.mFBWidth; |
| 172 | if (whf.h > info.mFBHeight) |
| 173 | mOVInfo.dst_rect.h = info.mFBHeight; |
| 174 | mSize = whf.size; |
| 175 | } |
| 176 | |
| 177 | |
| 178 | bool MdpCtrl::setInfo(RotatorBase* r, |
| 179 | const utils::PipeArgs& args, |
| 180 | const utils::ScreenInfo& info) |
| 181 | { |
| 182 | // new request |
| 183 | utils::Whf whf(args.whf); |
| 184 | mOVInfo.id = MSMFB_NEW_REQUEST; |
| 185 | |
| 186 | updateSource(r, args, info); |
| 187 | |
| 188 | setUserData(0); |
| 189 | mOVInfo.alpha = 0xff; |
| 190 | mOVInfo.transp_mask = 0xffffffff; |
| 191 | setZ(args.zorder); |
| 192 | setFlags(args.mdpFlags); |
| 193 | setWait(args.wait); |
| 194 | setIsFg(args.isFg); |
| 195 | mSize = whf.size; |
| 196 | return true; |
| 197 | } |
| 198 | |
| 199 | bool MdpCtrl::setCrop(const utils::Dim& cdim) { |
| 200 | utils::Dim d(cdim); |
| 201 | const utils::Whf ovwhf = getSrcWhf(); |
| 202 | int udata = getUserData(); |
| 203 | switch(udata) { |
| 204 | case MDP_ROT_NOP: |
| 205 | break; // nothing to do here |
| 206 | case MDP_ROT_90: |
| 207 | case MDP_ROT_90 | MDP_FLIP_UD: |
| 208 | case MDP_ROT_90 | MDP_FLIP_LR: |
| 209 | { |
| 210 | if (ovwhf.w < (d.y + d.h)) { |
| 211 | ALOGE("MdpCtrl setCrop failed ROT 90 udata=%d", |
| 212 | udata); |
| 213 | d.dump(); |
| 214 | this->dump(); |
| 215 | return false; |
| 216 | } |
| 217 | uint32_t tmp = d.x; |
| 218 | d.x = ovwhf.w - (d.y + d.h); |
| 219 | d.y = tmp; |
| 220 | utils::swap(d.w, d.h); |
| 221 | }break; |
| 222 | case MDP_ROT_270: |
| 223 | { |
| 224 | if (ovwhf.h < (d.x + d.w)) { |
| 225 | ALOGE("MdpCtrl setCrop failed ROT 270 udata=%d", |
| 226 | udata); |
| 227 | d.dump(); |
| 228 | this->dump(); |
| 229 | return false; |
| 230 | } |
| 231 | uint32_t tmp = d.y; |
| 232 | d.y = ovwhf.h - (d.x + d.w); |
| 233 | d.x = tmp; |
| 234 | utils::swap(d.w, d.h); |
| 235 | }break; |
| 236 | case MDP_ROT_180: |
| 237 | { |
| 238 | if ((ovwhf.h < (d.y + d.h)) || |
| 239 | (ovwhf.w < ( d.x + d.w))) { |
| 240 | ALOGE("MdpCtrl setCrop failed ROT 180 udata=%d", |
| 241 | udata); |
| 242 | d.dump(); |
| 243 | this->dump(); |
| 244 | return false; |
| 245 | } |
| 246 | d.x = ovwhf.w - (d.x + d.w); |
| 247 | d.y = ovwhf.h - (d.y + d.h); |
| 248 | }break; |
| 249 | default: |
| 250 | if(!(udata & (MDP_FLIP_UD | MDP_FLIP_LR))) { |
| 251 | ALOGE("MdpCtrl setCrop unknown rot %d", udata); |
| 252 | return false; |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | if(getSrcRectDim() == d) { |
| 257 | return true; // Nothing to do here |
| 258 | } |
| 259 | |
| 260 | utils::normalizeCrop(d.x, d.w); |
| 261 | utils::normalizeCrop(d.y, d.h); |
| 262 | |
| 263 | setSrcRectDim(d); |
| 264 | |
| 265 | return true; |
| 266 | } |
| 267 | |
| 268 | void MdpCtrl::dump() const { |
| 269 | ALOGE("== Dump MdpCtrl start =="); |
| 270 | ALOGE("size=%d", mSize); |
| 271 | mFd.dump(); |
| 272 | mdp_wrapper::dump("mOVInfo", mOVInfo); |
| 273 | ALOGE("== Dump MdpCtrl end =="); |
| 274 | } |
| 275 | |
| 276 | void MdpData::dump() const { |
| 277 | ALOGE("== Dump MdpData start =="); |
| 278 | mFd.dump(); |
| 279 | mdp_wrapper::dump("mOvData", mOvData); |
| 280 | ALOGE("== Dump MdpData end =="); |
| 281 | } |
| 282 | |
| 283 | void MdpCtrl3D::dump() const { |
| 284 | ALOGE("== Dump MdpCtrl start =="); |
| 285 | mFd.dump(); |
| 286 | ALOGE("== Dump MdpCtrl end =="); |
| 287 | } |
| 288 | |
| 289 | } // overlay |