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