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 #ifndef OVERLAY_MDP_H 19 #define OVERLAY_MDP_H 20 21 #include <linux/msm_mdp.h> 22 23 #include "overlayUtils.h" 24 #include "mdpWrapper.h" 25 #include "qdMetaData.h" 26 #ifdef USES_POST_PROCESSING 27 #include "lib-postproc.h" 28 #endif 29 30 namespace overlay{ 31 32 /* 33 * Mdp Ctrl holds corresponding fd and MDP related struct. 34 * It is simple wrapper to MDP services 35 * */ 36 class MdpCtrl { 37 public: 38 /* ctor reset */ 39 explicit MdpCtrl(); 40 /* dtor close */ 41 ~MdpCtrl(); 42 /* init underlying device using fbnum */ 43 bool init(uint32_t fbnum); 44 /* unset overlay, reset and close fd */ 45 bool close(); 46 /* reset and set ov id to -1 / MSMFB_NEW_REQUEST */ 47 void reset(); 48 /* calls overlay set 49 * Set would always consult last good known ov instance. 50 * Only if it is different, set would actually exectue ioctl. 51 * On a sucess ioctl. last good known ov instance is updated */ 52 bool set(); 53 /* Sets the source total width, height, format */ 54 void setSource(const utils::PipeArgs& pargs); 55 /* 56 * Sets ROI, the unpadded region, for source buffer. 57 * Dim - ROI dimensions. 58 */ 59 void setCrop(const utils::Dim& d); 60 void setTransform(const utils::eTransform& orient); 61 /* given a dim and w/h, set overlay dim */ 62 void setPosition(const utils::Dim& dim); 63 /* using user_data, sets/unsets roationvalue in mdp flags */ 64 void setRotationFlags(); 65 /* Performs downscale calculations */ 66 void setDownscale(int dscale_factor); 67 /* Update the src format with rotator's dest*/ 68 void updateSrcFormat(const uint32_t& rotDstFormat); 69 /* dump state of the object */ 70 void dump() const; 71 /* Return the dump in the specified buffer */ 72 void getDump(char *buf, size_t len); 73 74 /* returns session id */ 75 int getPipeId() const; 76 /* returns the fd associated to ctrl*/ 77 int getFd() const; 78 /* returns a copy ro dst rect dim */ 79 utils::Dim getDstRectDim() const; 80 /* returns a copy to src rect dim */ 81 utils::Dim getSrcRectDim() const; 82 /* setVisualParam */ 83 bool setVisualParams(const MetaData_t& data); 84 void forceSet(); 85 86 private: 87 /* Perform transformation calculations */ 88 void doTransform(); 89 void doDownscale(); 90 /* get orient / user_data[0] */ 91 int getOrient() const; 92 /* overlay get */ 93 bool get(); 94 /* returns flags from mdp structure */ 95 int getFlags() const; 96 /* set flags to mdp structure */ 97 void setFlags(int f); 98 /* set z order */ 99 void setZ(utils::eZorder z); 100 /* set isFg flag */ 101 void setIsFg(utils::eIsFg isFg); 102 /* return a copy of src whf*/ 103 utils::Whf getSrcWhf() const; 104 /* set plane alpha */ 105 void setPlaneAlpha(int planeAlpha); 106 /* set blending method */ 107 void setBlending(overlay::utils::eBlending blending); 108 109 /* set src whf */ 110 void setSrcWhf(const utils::Whf& whf); 111 /* set src/dst rect dim */ 112 void setSrcRectDim(const utils::Dim d); 113 void setDstRectDim(const utils::Dim d); 114 /* returns user_data[0]*/ 115 int getUserData() const; 116 /* sets user_data[0] */ 117 void setUserData(int v); 118 /* return true if current overlay is different 119 * than last known good overlay */ 120 bool ovChanged() const; 121 /* save mOVInfo to be last known good ov*/ 122 void save(); 123 /* restore last known good ov to be the current */ 124 void restore(); 125 126 utils::eTransform mOrientation; //Holds requested orientation 127 /* last good known ov info */ 128 mdp_overlay mLkgo; 129 /* Actual overlay mdp structure */ 130 mdp_overlay mOVInfo; 131 /* FD for the mdp fbnum */ 132 OvFD mFd; 133 int mDownscale; 134 bool mForceSet; 135 136 #ifdef USES_POST_PROCESSING 137 /* PP Compute Params */ 138 struct compute_params mParams; 139 /* indicate if PP params have been changed */ 140 bool mPPChanged; 141 #endif 142 }; 143 144 145 /* MDP 3D related ctrl */ 146 class MdpCtrl3D { 147 public: 148 /* ctor reset data */ 149 MdpCtrl3D(); 150 /* calls MSMFB_OVERLAY_3D */ 151 bool close(); 152 /* set w/h. format is ignored*/ 153 void setWh(const utils::Whf& whf); 154 /* set is_3d calls MSMFB_OVERLAY_3D */ 155 bool useVirtualFB(); 156 /* set fd to be used in ioctl */ 157 void setFd(int fd); 158 /* dump */ 159 void dump() const; 160 private: 161 /* reset */ 162 void reset(); 163 /* actual MSM 3D info */ 164 msmfb_overlay_3d m3DOVInfo; 165 /* FD for the mdp 3D */ 166 OvFD mFd; 167 }; 168 169 /* MDP data */ 170 class MdpData { 171 public: 172 /* ctor reset data */ 173 explicit MdpData(); 174 /* dtor close*/ 175 ~MdpData(); 176 /* init FD */ 177 bool init(uint32_t fbnum); 178 /* memset0 the underlying mdp object */ 179 void reset(); 180 /* close fd, and reset */ 181 bool close(); 182 /* set id of mdp data */ 183 void setPipeId(int id); 184 /* return ses id of data */ 185 int getPipeId() const; 186 /* get underlying fd*/ 187 int getFd() const; 188 /* get memory_id */ 189 int getSrcMemoryId() const; 190 /* calls wrapper play */ 191 bool play(int fd, uint32_t offset); 192 /* dump state of the object */ 193 void dump() const; 194 /* Return the dump in the specified buffer */ 195 void getDump(char *buf, size_t len); 196 197 private: 198 199 /* actual overlay mdp data */ 200 msmfb_overlay_data mOvData; 201 /* fd to mdp fbnum */ 202 OvFD mFd; 203 }; 204 205 //--------------Inlines--------------------------------- 206 207 ///// MdpCtrl ////// 208 209 inline MdpCtrl::MdpCtrl() { 210 reset(); 211 } 212 213 inline MdpCtrl::~MdpCtrl() { 214 close(); 215 } 216 217 inline int MdpCtrl::getOrient() const { 218 return getUserData(); 219 } 220 221 inline int MdpCtrl::getPipeId() const { 222 return mOVInfo.id; 223 } 224 225 inline int MdpCtrl::getFd() const { 226 return mFd.getFD(); 227 } 228 229 inline int MdpCtrl::getFlags() const { 230 return mOVInfo.flags; 231 } 232 233 inline void MdpCtrl::setFlags(int f) { 234 mOVInfo.flags = f; 235 } 236 237 inline void MdpCtrl::setZ(overlay::utils::eZorder z) { 238 mOVInfo.z_order = z; 239 } 240 241 inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) { 242 mOVInfo.is_fg = isFg; 243 } 244 245 inline void MdpCtrl::setDownscale(int dscale) { 246 mDownscale = dscale; 247 } 248 249 inline void MdpCtrl::setPlaneAlpha(int planeAlpha) { 250 mOVInfo.alpha = planeAlpha; 251 } 252 253 inline void MdpCtrl::setBlending(overlay::utils::eBlending blending) { 254 switch((int) blending) { 255 case utils::OVERLAY_BLENDING_OPAQUE: 256 mOVInfo.blend_op = BLEND_OP_OPAQUE; 257 break; 258 case utils::OVERLAY_BLENDING_PREMULT: 259 mOVInfo.blend_op = BLEND_OP_PREMULTIPLIED; 260 break; 261 case utils::OVERLAY_BLENDING_COVERAGE: 262 default: 263 mOVInfo.blend_op = BLEND_OP_COVERAGE; 264 } 265 } 266 267 inline bool MdpCtrl::ovChanged() const { 268 #ifdef USES_POST_PROCESSING 269 // Some pp params are stored as pointer address, 270 // so can't compare their content directly. 271 if (mPPChanged) { 272 return true; 273 } 274 #endif 275 // 0 means same 276 if(0 == ::memcmp(&mOVInfo, &mLkgo, sizeof (mdp_overlay))) { 277 return false; 278 } 279 return true; 280 } 281 282 inline void MdpCtrl::save() { 283 if(static_cast<ssize_t>(mOVInfo.id) == MSMFB_NEW_REQUEST) { 284 ALOGE("MdpCtrl current ov has id -1, will not save"); 285 return; 286 } 287 mLkgo = mOVInfo; 288 } 289 290 inline void MdpCtrl::restore() { 291 if(static_cast<ssize_t>(mLkgo.id) == MSMFB_NEW_REQUEST) { 292 ALOGE("MdpCtrl Lkgo ov has id -1, will not restore"); 293 return; 294 } 295 mOVInfo = mLkgo; 296 } 297 298 inline overlay::utils::Whf MdpCtrl::getSrcWhf() const { 299 return utils::Whf( mOVInfo.src.width, 300 mOVInfo.src.height, 301 mOVInfo.src.format); 302 } 303 304 inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) { 305 mOVInfo.src.width = whf.w; 306 mOVInfo.src.height = whf.h; 307 mOVInfo.src.format = whf.format; 308 } 309 310 inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const { 311 return utils::Dim( mOVInfo.src_rect.x, 312 mOVInfo.src_rect.y, 313 mOVInfo.src_rect.w, 314 mOVInfo.src_rect.h); 315 } 316 317 inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) { 318 mOVInfo.src_rect.x = d.x; 319 mOVInfo.src_rect.y = d.y; 320 mOVInfo.src_rect.w = d.w; 321 mOVInfo.src_rect.h = d.h; 322 } 323 324 inline overlay::utils::Dim MdpCtrl::getDstRectDim() const { 325 return utils::Dim( mOVInfo.dst_rect.x, 326 mOVInfo.dst_rect.y, 327 mOVInfo.dst_rect.w, 328 mOVInfo.dst_rect.h); 329 } 330 331 inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) { 332 mOVInfo.dst_rect.x = d.x; 333 mOVInfo.dst_rect.y = d.y; 334 mOVInfo.dst_rect.w = d.w; 335 mOVInfo.dst_rect.h = d.h; 336 } 337 338 inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; } 339 340 inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; } 341 342 inline void MdpCtrl::setRotationFlags() { 343 const int u = getUserData(); 344 if (u & MDP_ROT_90) 345 mOVInfo.flags |= MDP_SOURCE_ROTATED_90; 346 } 347 348 inline void MdpCtrl::forceSet() { 349 mForceSet = true; 350 } 351 352 /////// MdpCtrl3D ////// 353 354 inline MdpCtrl3D::MdpCtrl3D() { reset(); } 355 inline bool MdpCtrl3D::close() { 356 if (m3DOVInfo.is_3d) { 357 m3DOVInfo.is_3d = 0; 358 if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) { 359 ALOGE("MdpCtrl3D close failed set3D with 0"); 360 return false; 361 } 362 } 363 reset(); 364 return true; 365 } 366 inline void MdpCtrl3D::reset() { 367 utils::memset0(m3DOVInfo); 368 } 369 370 inline void MdpCtrl3D::setFd(int fd) { 371 mFd.copy(fd); 372 OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid"); 373 } 374 375 inline void MdpCtrl3D::setWh(const utils::Whf& whf) { 376 // ignore fmt. Needed for useVirtualFB callflow 377 m3DOVInfo.width = whf.w; 378 m3DOVInfo.height = whf.h; 379 } 380 381 inline bool MdpCtrl3D::useVirtualFB() { 382 if(!m3DOVInfo.is_3d) { 383 m3DOVInfo.is_3d = 1; 384 if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) { 385 ALOGE("MdpCtrl3D close failed set3D with 0"); 386 return false; 387 } 388 } 389 return true; 390 } 391 392 /////// MdpData ////// 393 394 inline MdpData::MdpData() { reset(); } 395 396 inline MdpData::~MdpData() { close(); } 397 398 inline bool MdpData::init(uint32_t fbnum) { 399 // FD init 400 if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){ 401 ALOGE("Ctrl failed to init fbnum=%d", fbnum); 402 return false; 403 } 404 return true; 405 } 406 407 inline void MdpData::reset() { 408 overlay::utils::memset0(mOvData); 409 mOvData.data.memory_id = -1; 410 } 411 412 inline bool MdpData::close() { 413 reset(); 414 return mFd.close(); 415 } 416 417 inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; } 418 419 inline void MdpData::setPipeId(int id) { mOvData.id = id; } 420 421 inline int MdpData::getPipeId() const { return mOvData.id; } 422 423 inline int MdpData::getFd() const { return mFd.getFD(); } 424 425 inline bool MdpData::play(int fd, uint32_t offset) { 426 mOvData.data.memory_id = fd; 427 mOvData.data.offset = offset; 428 if(!mdp_wrapper::play(mFd.getFD(), mOvData)){ 429 ALOGE("MdpData failed to play"); 430 dump(); 431 return false; 432 } 433 return true; 434 } 435 436 } // overlay 437 438 #endif // OVERLAY_MDP_H 439