1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2010-2013, The Linux Foundation. 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 <math.h> 19 #include <mdp_version.h> 20 #include "overlayUtils.h" 21 #include "overlayMdp.h" 22 #include "mdp_version.h" 23 24 #define HSIC_SETTINGS_DEBUG 0 25 26 using namespace qdutils; 27 28 static inline bool isEqual(float f1, float f2) { 29 return ((int)(f1*100) == (int)(f2*100)) ? true : false; 30 } 31 32 namespace ovutils = overlay::utils; 33 namespace overlay { 34 35 bool MdpCtrl::init(uint32_t fbnum) { 36 // FD init 37 if(!utils::openDev(mFd, fbnum, 38 Res::fbPath, O_RDWR)){ 39 ALOGE("Ctrl failed to init fbnum=%d", fbnum); 40 return false; 41 } 42 return true; 43 } 44 45 void MdpCtrl::reset() { 46 utils::memset0(mOVInfo); 47 utils::memset0(mLkgo); 48 mOVInfo.id = MSMFB_NEW_REQUEST; 49 mLkgo.id = MSMFB_NEW_REQUEST; 50 mOrientation = utils::OVERLAY_TRANSFORM_0; 51 mDownscale = 0; 52 mForceSet = false; 53 #ifdef USES_POST_PROCESSING 54 mPPChanged = false; 55 memset(&mParams, 0, sizeof(struct compute_params)); 56 mParams.params.conv_params.order = hsic_order_hsc_i; 57 mParams.params.conv_params.interface = interface_rec601; 58 mParams.params.conv_params.cc_matrix[0][0] = 1; 59 mParams.params.conv_params.cc_matrix[1][1] = 1; 60 mParams.params.conv_params.cc_matrix[2][2] = 1; 61 #endif 62 } 63 64 bool MdpCtrl::close() { 65 bool result = true; 66 if(MSMFB_NEW_REQUEST != static_cast<int>(mOVInfo.id)) { 67 if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) { 68 ALOGE("MdpCtrl close error in unset"); 69 result = false; 70 } 71 } 72 #ifdef USES_POST_PROCESSING 73 /* free allocated memory in PP */ 74 if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data) 75 free(mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data); 76 #endif 77 reset(); 78 79 if(!mFd.close()) { 80 result = false; 81 } 82 83 return result; 84 } 85 86 void MdpCtrl::setSource(const utils::PipeArgs& args) { 87 setSrcWhf(args.whf); 88 89 //TODO These are hardcoded. Can be moved out of setSource. 90 mOVInfo.transp_mask = 0xffffffff; 91 92 //TODO These calls should ideally be a part of setPipeParams API 93 setFlags(args.mdpFlags); 94 setZ(args.zorder); 95 setIsFg(args.isFg); 96 setPlaneAlpha(args.planeAlpha); 97 setBlending(args.blending); 98 } 99 100 void MdpCtrl::setCrop(const utils::Dim& d) { 101 setSrcRectDim(d); 102 } 103 104 void MdpCtrl::setPosition(const overlay::utils::Dim& d) { 105 setDstRectDim(d); 106 } 107 108 void MdpCtrl::setTransform(const utils::eTransform& orient) { 109 int rot = utils::getMdpOrient(orient); 110 setUserData(rot); 111 mOrientation = static_cast<utils::eTransform>(rot); 112 } 113 114 void MdpCtrl::doTransform() { 115 setRotationFlags(); 116 utils::Whf whf = getSrcWhf(); 117 utils::Dim dim = getSrcRectDim(); 118 utils::preRotateSource(mOrientation, whf, dim); 119 setSrcWhf(whf); 120 setSrcRectDim(dim); 121 } 122 123 void MdpCtrl::doDownscale() { 124 int mdpVersion = MDPVersion::getInstance().getMDPVersion(); 125 if(mdpVersion < MDSS_V5) { 126 mOVInfo.src_rect.x >>= mDownscale; 127 mOVInfo.src_rect.y >>= mDownscale; 128 mOVInfo.src_rect.w >>= mDownscale; 129 mOVInfo.src_rect.h >>= mDownscale; 130 } else if(MDPVersion::getInstance().supportsDecimation()) { 131 utils::getDecimationFactor(mOVInfo.src_rect.w, mOVInfo.src_rect.h, 132 mOVInfo.dst_rect.w, mOVInfo.dst_rect.h, mOVInfo.horz_deci, 133 mOVInfo.vert_deci); 134 } 135 } 136 137 bool MdpCtrl::set() { 138 int mdpVersion = MDPVersion::getInstance().getMDPVersion(); 139 //deferred calcs, so APIs could be called in any order. 140 doTransform(); 141 utils::Whf whf = getSrcWhf(); 142 if(utils::isYuv(whf.format)) { 143 utils::normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w); 144 utils::normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h); 145 if(mdpVersion < MDSS_V5) { 146 utils::even_floor(mOVInfo.dst_rect.w); 147 utils::even_floor(mOVInfo.dst_rect.h); 148 } else if (mOVInfo.flags & MDP_DEINTERLACE) { 149 // For interlaced, crop.h should be 4-aligned 150 if (!(mOVInfo.flags & MDP_SOURCE_ROTATED_90) && 151 (mOVInfo.src_rect.h % 4)) 152 mOVInfo.src_rect.h = utils::aligndown(mOVInfo.src_rect.h, 4); 153 } 154 } else { 155 if (mdpVersion >= MDSS_V5) { 156 // Check for 1-pixel down-scaling 157 if (mOVInfo.src_rect.w - mOVInfo.dst_rect.w == 1) 158 mOVInfo.src_rect.w -= 1; 159 if (mOVInfo.src_rect.h - mOVInfo.dst_rect.h == 1) 160 mOVInfo.src_rect.h -= 1; 161 } 162 } 163 164 doDownscale(); 165 166 if(this->ovChanged() || mForceSet) { 167 mForceSet = false; 168 if(!mdp_wrapper::setOverlay(mFd.getFD(), mOVInfo)) { 169 ALOGE("MdpCtrl failed to setOverlay, restoring last known " 170 "good ov info"); 171 mdp_wrapper::dump("== Bad OVInfo is: ", mOVInfo); 172 mdp_wrapper::dump("== Last good known OVInfo is: ", mLkgo); 173 this->restore(); 174 return false; 175 } 176 this->save(); 177 } 178 179 return true; 180 } 181 182 bool MdpCtrl::get() { 183 mdp_overlay ov; 184 ov.id = mOVInfo.id; 185 if (!mdp_wrapper::getOverlay(mFd.getFD(), ov)) { 186 ALOGE("MdpCtrl get failed"); 187 return false; 188 } 189 mOVInfo = ov; 190 return true; 191 } 192 193 //Update src format based on rotator's destination format. 194 void MdpCtrl::updateSrcFormat(const uint32_t& rotDestFmt) { 195 utils::Whf whf = getSrcWhf(); 196 whf.format = rotDestFmt; 197 setSrcWhf(whf); 198 } 199 200 void MdpCtrl::dump() const { 201 ALOGE("== Dump MdpCtrl start =="); 202 mFd.dump(); 203 mdp_wrapper::dump("mOVInfo", mOVInfo); 204 ALOGE("== Dump MdpCtrl end =="); 205 } 206 207 void MdpCtrl::getDump(char *buf, size_t len) { 208 ovutils::getDump(buf, len, "Ctrl", mOVInfo); 209 } 210 211 void MdpData::dump() const { 212 ALOGE("== Dump MdpData start =="); 213 mFd.dump(); 214 mdp_wrapper::dump("mOvData", mOvData); 215 ALOGE("== Dump MdpData end =="); 216 } 217 218 void MdpData::getDump(char *buf, size_t len) { 219 ovutils::getDump(buf, len, "Data", mOvData); 220 } 221 222 void MdpCtrl3D::dump() const { 223 ALOGE("== Dump MdpCtrl start =="); 224 mFd.dump(); 225 ALOGE("== Dump MdpCtrl end =="); 226 } 227 228 bool MdpCtrl::setVisualParams(const MetaData_t& data) { 229 #ifdef USES_POST_PROCESSING 230 bool needUpdate = false; 231 /* calculate the data */ 232 if (data.operation & PP_PARAM_HSIC) { 233 if (mParams.params.pa_params.hue != data.hsicData.hue) { 234 ALOGD_IF(HSIC_SETTINGS_DEBUG, 235 "Hue has changed from %d to %d", 236 mParams.params.pa_params.hue,data.hsicData.hue); 237 needUpdate = true; 238 } 239 240 if (!isEqual(mParams.params.pa_params.sat, 241 data.hsicData.saturation)) { 242 ALOGD_IF(HSIC_SETTINGS_DEBUG, 243 "Saturation has changed from %f to %f", 244 mParams.params.pa_params.sat, 245 data.hsicData.saturation); 246 needUpdate = true; 247 } 248 249 if (mParams.params.pa_params.intensity != data.hsicData.intensity) { 250 ALOGD_IF(HSIC_SETTINGS_DEBUG, 251 "Intensity has changed from %d to %d", 252 mParams.params.pa_params.intensity, 253 data.hsicData.intensity); 254 needUpdate = true; 255 } 256 257 if (!isEqual(mParams.params.pa_params.contrast, 258 data.hsicData.contrast)) { 259 ALOGD_IF(HSIC_SETTINGS_DEBUG, 260 "Contrast has changed from %f to %f", 261 mParams.params.pa_params.contrast, 262 data.hsicData.contrast); 263 needUpdate = true; 264 } 265 266 if (needUpdate) { 267 mParams.params.pa_params.hue = data.hsicData.hue; 268 mParams.params.pa_params.sat = data.hsicData.saturation; 269 mParams.params.pa_params.intensity = data.hsicData.intensity; 270 mParams.params.pa_params.contrast = data.hsicData.contrast; 271 mParams.params.pa_params.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE; 272 mParams.operation |= PP_OP_PA; 273 } 274 } 275 276 if (data.operation & PP_PARAM_SHARP2) { 277 if (mParams.params.sharp_params.strength != data.Sharp2Data.strength) { 278 needUpdate = true; 279 } 280 if (mParams.params.sharp_params.edge_thr != data.Sharp2Data.edge_thr) { 281 needUpdate = true; 282 } 283 if (mParams.params.sharp_params.smooth_thr != 284 data.Sharp2Data.smooth_thr) { 285 needUpdate = true; 286 } 287 if (mParams.params.sharp_params.noise_thr != 288 data.Sharp2Data.noise_thr) { 289 needUpdate = true; 290 } 291 292 if (needUpdate) { 293 mParams.params.sharp_params.strength = data.Sharp2Data.strength; 294 mParams.params.sharp_params.edge_thr = data.Sharp2Data.edge_thr; 295 mParams.params.sharp_params.smooth_thr = 296 data.Sharp2Data.smooth_thr; 297 mParams.params.sharp_params.noise_thr = data.Sharp2Data.noise_thr; 298 mParams.params.sharp_params.ops = 299 MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE; 300 mParams.operation |= PP_OP_SHARP; 301 } 302 } 303 304 if (data.operation & PP_PARAM_IGC) { 305 if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data == NULL){ 306 uint32_t *igcData 307 = (uint32_t *)malloc(2 * MAX_IGC_LUT_ENTRIES * sizeof(uint32_t)); 308 if (!igcData) { 309 ALOGE("IGC storage allocated failed"); 310 return false; 311 } 312 mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data = igcData; 313 mOVInfo.overlay_pp_cfg.igc_cfg.c2_data 314 = igcData + MAX_IGC_LUT_ENTRIES; 315 } 316 317 memcpy(mParams.params.igc_lut_params.c0, 318 data.igcData.c0, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES); 319 memcpy(mParams.params.igc_lut_params.c1, 320 data.igcData.c1, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES); 321 memcpy(mParams.params.igc_lut_params.c2, 322 data.igcData.c2, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES); 323 324 mParams.params.igc_lut_params.ops 325 = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE; 326 mParams.operation |= PP_OP_IGC; 327 needUpdate = true; 328 } 329 330 if (data.operation & PP_PARAM_VID_INTFC) { 331 mParams.params.conv_params.interface = 332 (interface_type) data.video_interface; 333 needUpdate = true; 334 } 335 336 if (needUpdate) { 337 display_pp_compute_params(&mParams, &mOVInfo.overlay_pp_cfg); 338 mPPChanged = true; 339 } 340 #endif 341 return true; 342 } 343 344 } // overlay 345