1/* 2* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3* 4* Redistribution and use in source and binary forms, with or without 5* modification, are permitted provided that the following conditions are 6* met: 7* * Redistributions of source code must retain the above copyright 8* notice, this list of conditions and the following disclaimer. 9* * Redistributions in binary form must reproduce the above 10* copyright notice, this list of conditions and the following 11* disclaimer in the documentation and/or other materials provided 12* with the distribution. 13* * Neither the name of The Linux Foundation nor the names of its 14* contributors may be used to endorse or promote products derived 15* from this software without specific prior written permission. 16* 17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*/ 29 30#ifndef OVERLAY_M3D_EXT_PIPE_H 31#define OVERLAY_M3D_EXT_PIPE_H 32 33#include "overlayGenPipe.h" 34#include "overlayUtils.h" 35 36namespace overlay { 37 38///////////// M3DExt Pipe //////////////////////////// 39/** 40* A specific impl of GenericPipe for 3D. 41* Whenever needed to have a pass through - we do it. 42* If there is a special need for special/diff behavior 43* do it here 44* PANEL is always EXTERNAL for this pipe. 45* CHAN = 0,1 it's either Channel 1 or channel 2 needed for 46* 3D crop and position */ 47template <int CHAN> 48class M3DExtPipe : utils::NoCopy { 49public: 50 /* Please look at overlayGenPipe.h for info */ 51 explicit M3DExtPipe(); 52 ~M3DExtPipe(); 53 bool init(RotatorBase* rot); 54 bool close(); 55 bool commit(); 56 bool queueBuffer(int fd, uint32_t offset); 57 bool setCrop(const utils::Dim& d); 58 bool setPosition(const utils::Dim& dim); 59 bool setTransform(const utils::eTransform& param); 60 bool setSource(const utils::PipeArgs& args); 61 void dump() const; 62private: 63 overlay::GenericPipe<utils::EXTERNAL> mM3d; 64 // Cache the M3D format 65 uint32_t mM3Dfmt; 66}; 67 68///////////// M3DPrimary Pipe //////////////////////////// 69/** 70* A specific impl of GenericPipe for 3D. 71* Whenever needed to have a pass through - we do it. 72* If there is a special need for special/diff behavior 73* do it here 74* PANEL is always PRIMARY for this pipe. 75* CHAN = 0,1 it's either Channel 1 or channel 2 needed for 76* 3D crop and position */ 77template <int CHAN> 78class M3DPrimaryPipe : utils::NoCopy { 79public: 80 /* Please look at overlayGenPipe.h for info */ 81 explicit M3DPrimaryPipe(); 82 ~M3DPrimaryPipe(); 83 bool init(RotatorBase* rot); 84 bool close(); 85 bool commit(); 86 bool queueBuffer(int fd, uint32_t offset); 87 bool setCrop(const utils::Dim& d); 88 bool setPosition(const utils::Dim& dim); 89 bool setTransform(const utils::eTransform& param); 90 bool setSource(const utils::PipeArgs& args); 91 void dump() const; 92private: 93 overlay::GenericPipe<utils::PRIMARY> mM3d; 94 // Cache the M3D format 95 uint32_t mM3Dfmt; 96}; 97 98///////////// S3DExt Pipe //////////////////////////////// 99/** 100* A specific impl of GenericPipe for 3D. 101* Whenever needed to have a pass through - we do it. 102* If there is a special need for special/diff behavior 103* do it here. 104* PANEL is always EXTERNAL for this pipe. 105* CHAN = 0,1 it's either Channel 1 or channel 2 needed for 106* 3D crop and position */ 107template <int CHAN> 108class S3DExtPipe : utils::NoCopy { 109public: 110 /* Please look at overlayGenPipe.h for info */ 111 explicit S3DExtPipe(); 112 ~S3DExtPipe(); 113 bool init(RotatorBase* rot); 114 bool close(); 115 bool commit(); 116 bool queueBuffer(int fd, uint32_t offset); 117 bool setCrop(const utils::Dim& d); 118 bool setPosition(const utils::Dim& dim); 119 bool setTransform(const utils::eTransform& param); 120 bool setSource(const utils::PipeArgs& args); 121 void dump() const; 122private: 123 overlay::GenericPipe<utils::EXTERNAL> mS3d; 124 // Cache the 3D format 125 uint32_t mS3Dfmt; 126}; 127 128///////////// S3DPrimary Pipe //////////////////////////// 129/** 130* A specific impl of GenericPipe for 3D. 131* Whenever needed to have a pass through - we do it. 132* If there is a special need for special/diff behavior 133* do it here 134* PANEL is always PRIMARY for this pipe. 135* CHAN = 0,1 it's either Channel 1 or channel 2 needed for 136* 3D crop and position */ 137template <int CHAN> 138class S3DPrimaryPipe : utils::NoCopy { 139public: 140 /* Please look at overlayGenPipe.h for info */ 141 explicit S3DPrimaryPipe(); 142 ~S3DPrimaryPipe(); 143 bool init(RotatorBase* rot); 144 bool close(); 145 bool commit(); 146 bool queueBuffer(int fd, uint32_t offset); 147 bool setCrop(const utils::Dim& d); 148 bool setPosition(const utils::Dim& dim); 149 bool setTransform(const utils::eTransform& param); 150 bool setSource(const utils::PipeArgs& args); 151 void dump() const; 152private: 153 /* needed for 3D related IOCTL */ 154 MdpCtrl3D mCtrl3D; 155 overlay::GenericPipe<utils::PRIMARY> mS3d; 156 // Cache the 3D format 157 uint32_t mS3Dfmt; 158}; 159 160 161 162 163//------------------------Inlines and Templates-------------------------- 164 165 166///////////// M3DExt Pipe //////////////////////////// 167template <int CHAN> 168inline M3DExtPipe<CHAN>::M3DExtPipe() : mM3Dfmt(0) {} 169template <int CHAN> 170inline M3DExtPipe<CHAN>::~M3DExtPipe() { close(); } 171template <int CHAN> 172inline bool M3DExtPipe<CHAN>::init(RotatorBase* rot) { 173 ALOGE_IF(DEBUG_OVERLAY, "M3DExtPipe init"); 174 if(!mM3d.init(rot)) { 175 ALOGE("3Dpipe failed to init"); 176 return false; 177 } 178 return true; 179} 180template <int CHAN> 181inline bool M3DExtPipe<CHAN>::close() { 182 return mM3d.close(); 183} 184template <int CHAN> 185inline bool M3DExtPipe<CHAN>::commit() { return mM3d.commit(); } 186template <int CHAN> 187inline bool M3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 188 return mM3d.queueBuffer(fd, offset); 189} 190template <int CHAN> 191inline bool M3DExtPipe<CHAN>::setCrop(const utils::Dim& d) { 192 utils::Dim _dim; 193 if(!utils::getCropS3D<CHAN>(d, _dim, mM3Dfmt)){ 194 ALOGE("M3DExtPipe setCrop failed to getCropS3D"); 195 _dim = d; 196 } 197 return mM3d.setCrop(_dim); 198} 199 200template <int CHAN> 201inline bool M3DExtPipe<CHAN>::setPosition(const utils::Dim& d) { 202 utils::Dim _dim; 203 // original setPositionHandleState has getPositionS3D(...,true) 204 // which means format is HAL_3D_OUT_SBS_MASK 205 // HAL_3D_OUT_SBS_MASK is 0x1000 >> 12 == 0x1 as the orig 206 // code suggets 207 utils::Whf _whf(mM3d.getScreenInfo().mFBWidth, 208 mM3d.getScreenInfo().mFBHeight, 209 mM3Dfmt); 210 if(!utils::getPositionS3D<CHAN>(_whf, _dim)) { 211 ALOGE("S3DPrimaryPipe setPosition err in getPositionS3D"); 212 _dim = d; 213 } 214 return mM3d.setPosition(_dim); 215} 216template <int CHAN> 217inline bool M3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) { 218 return mM3d.setTransform(param); 219} 220template <int CHAN> 221inline bool M3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) 222{ 223 // extract 3D fmt 224 mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) | 225 utils::HAL_3D_OUT_MONOS_MASK; 226 return mM3d.setSource(args); 227} 228template <int CHAN> 229inline void M3DExtPipe<CHAN>::dump() const { 230 ALOGE("M3DExtPipe Pipe fmt=%d", mM3Dfmt); 231 mM3d.dump(); 232} 233 234 235///////////// M3DPrimary Pipe //////////////////////////// 236template <int CHAN> 237inline M3DPrimaryPipe<CHAN>::M3DPrimaryPipe() : mM3Dfmt(0) {} 238template <int CHAN> 239inline M3DPrimaryPipe<CHAN>::~M3DPrimaryPipe() { close(); } 240template <int CHAN> 241inline bool M3DPrimaryPipe<CHAN>::init(RotatorBase* rot) { 242 ALOGE_IF(DEBUG_OVERLAY, "M3DPrimaryPipe init"); 243 if(!mM3d.init(rot)) { 244 ALOGE("3Dpipe failed to init"); 245 return false; 246 } 247 return true; 248} 249template <int CHAN> 250inline bool M3DPrimaryPipe<CHAN>::close() { 251 return mM3d.close(); 252} 253template <int CHAN> 254inline bool M3DPrimaryPipe<CHAN>::commit() { return mM3d.commit(); } 255template <int CHAN> 256inline bool M3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 257 return mM3d.queueBuffer(fd, offset); 258} 259template <int CHAN> 260inline bool M3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) { 261 utils::Dim _dim; 262 if(!utils::getCropS3D<CHAN>(d, _dim, mM3Dfmt)){ 263 ALOGE("M3DPrimaryPipe setCrop failed to getCropS3D"); 264 _dim = d; 265 } 266 return mM3d.setCrop(_dim); 267} 268template <int CHAN> 269inline bool M3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) { 270 return mM3d.setPosition(d); 271} 272template <int CHAN> 273inline bool M3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) { 274 return mM3d.setTransform(param); 275} 276template <int CHAN> 277inline bool M3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args) 278{ 279 // extract 3D fmt 280 mM3Dfmt = utils::format3DInput(utils::getS3DFormat(args.whf.format)) | 281 utils::HAL_3D_OUT_MONOS_MASK; 282 return mM3d.setSource(args); 283} 284template <int CHAN> 285inline void M3DPrimaryPipe<CHAN>::dump() const { 286 ALOGE("M3DPrimaryPipe Pipe fmt=%d", mM3Dfmt); 287 mM3d.dump(); 288} 289 290///////////// S3DExt Pipe //////////////////////////////// 291template <int CHAN> 292inline S3DExtPipe<CHAN>::S3DExtPipe() : mS3Dfmt(0) {} 293template <int CHAN> 294inline S3DExtPipe<CHAN>::~S3DExtPipe() { close(); } 295template <int CHAN> 296inline bool S3DExtPipe<CHAN>::init(RotatorBase* rot) { 297 ALOGE_IF(DEBUG_OVERLAY, "S3DExtPipe init"); 298 if(!mS3d.init(rot)) { 299 ALOGE("3Dpipe failed to init"); 300 return false; 301 } 302 return true; 303} 304template <int CHAN> 305inline bool S3DExtPipe<CHAN>::close() { 306 if(!utils::send3DInfoPacket(0)) { 307 ALOGE("S3DExtPipe close failed send3D info packet"); 308 } 309 return mS3d.close(); 310} 311template <int CHAN> 312inline bool S3DExtPipe<CHAN>::commit() { return mS3d.commit(); } 313template <int CHAN> 314inline bool S3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 315 return mS3d.queueBuffer(fd, offset); 316} 317template <int CHAN> 318inline bool S3DExtPipe<CHAN>::setCrop(const utils::Dim& d) { 319 utils::Dim _dim; 320 if(!utils::getCropS3D<CHAN>(d, _dim, mS3Dfmt)){ 321 ALOGE("S3DExtPipe setCrop failed to getCropS3D"); 322 _dim = d; 323 } 324 return mS3d.setCrop(_dim); 325} 326template <int CHAN> 327inline bool S3DExtPipe<CHAN>::setPosition(const utils::Dim& d) 328{ 329 utils::Dim _dim; 330 utils::Whf _whf(mS3d.getScreenInfo().mFBWidth, 331 mS3d.getScreenInfo().mFBHeight, 332 mS3Dfmt); 333 if(!utils::getPositionS3D<CHAN>(_whf, _dim)) { 334 ALOGE("S3DExtPipe setPosition err in getPositionS3D"); 335 _dim = d; 336 } 337 return mS3d.setPosition(_dim); 338} 339template <int CHAN> 340inline bool S3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) { 341 return mS3d.setTransform(param); 342} 343template <int CHAN> 344inline bool S3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) { 345 mS3Dfmt = utils::getS3DFormat(args.whf.format); 346 return mS3d.setSource(args); 347} 348template <int CHAN> 349inline void S3DExtPipe<CHAN>::dump() const { 350 ALOGE("S3DExtPipe Pipe fmt=%d", mS3Dfmt); 351 mS3d.dump(); 352} 353 354///////////// S3DPrimary Pipe //////////////////////////// 355template <int CHAN> 356inline S3DPrimaryPipe<CHAN>::S3DPrimaryPipe() : mS3Dfmt(0) {} 357template <int CHAN> 358inline S3DPrimaryPipe<CHAN>::~S3DPrimaryPipe() { close(); } 359template <int CHAN> 360inline bool S3DPrimaryPipe<CHAN>::init(RotatorBase* rot) { 361 ALOGE_IF(DEBUG_OVERLAY, "S3DPrimaryPipe init"); 362 if(!mS3d.init(rot)) { 363 ALOGE("3Dpipe failed to init"); 364 return false; 365 } 366 // set the ctrl fd 367 mCtrl3D.setFd(mS3d.getCtrlFd()); 368 return true; 369} 370template <int CHAN> 371inline bool S3DPrimaryPipe<CHAN>::close() { 372 if(!utils::enableBarrier(0)) { 373 ALOGE("S3DExtPipe close failed enable barrier"); 374 } 375 mCtrl3D.close(); 376 return mS3d.close(); 377} 378 379template <int CHAN> 380inline bool S3DPrimaryPipe<CHAN>::commit() { 381 uint32_t fmt = mS3Dfmt & utils::OUTPUT_3D_MASK; 382 if(!utils::send3DInfoPacket(fmt)){ 383 ALOGE("Error S3DExtPipe start error send3DInfoPacket %d", fmt); 384 return false; 385 } 386 return mS3d.commit(); 387} 388template <int CHAN> 389inline bool S3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 390 return mS3d.queueBuffer(fd, offset); 391} 392template <int CHAN> 393inline bool S3DPrimaryPipe<CHAN>::setCrop(const utils::Dim& d) { 394 utils::Dim _dim; 395 if(!utils::getCropS3D<CHAN>(d, _dim, mS3Dfmt)){ 396 ALOGE("S3DPrimaryPipe setCrop failed to getCropS3D"); 397 _dim = d; 398 } 399 return mS3d.setCrop(_dim); 400} 401template <int CHAN> 402inline bool S3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) 403{ 404 utils::Whf fbwhf(mS3d.getScreenInfo().mFBWidth, 405 mS3d.getScreenInfo().mFBHeight, 406 0 /* fmt dont care*/); 407 mCtrl3D.setWh(fbwhf); 408 if(!mCtrl3D.useVirtualFB()) { 409 ALOGE("Failed to use VFB on %d (non fatal)", utils::FB0); 410 return false; 411 } 412 utils::Dim _dim; 413 // original setPositionHandleState has getPositionS3D(...,true) 414 // which means format is HAL_3D_OUT_SBS_MASK 415 // HAL_3D_OUT_SBS_MASK is 0x1000 >> 12 == 0x1 as the orig 416 // code suggets 417 utils::Whf _whf(d.w, d.h, utils::HAL_3D_OUT_SBS_MASK); 418 if(!utils::getPositionS3D<CHAN>(_whf, _dim)) { 419 ALOGE("S3DPrimaryPipe setPosition err in getPositionS3D"); 420 _dim = d; 421 } 422 return mS3d.setPosition(_dim); 423} 424 425/* for S3DPrimaryPipe, we need to have barriers once 426* So the easiest way to achieve it, is to make sure FB0 is having it before 427* setParam is running */ 428template <> 429inline bool S3DPrimaryPipe<utils::OV_PIPE0>::setTransform( 430 const utils::eTransform& param) { 431 uint32_t barrier=0; 432 switch(param) { 433 case utils::OVERLAY_TRANSFORM_ROT_90: 434 case utils::OVERLAY_TRANSFORM_ROT_270: 435 barrier = utils::BARRIER_LAND; 436 break; 437 default: 438 barrier = utils::BARRIER_PORT; 439 break; 440 } 441 if(!utils::enableBarrier(barrier)) { 442 ALOGE("S3DPrimaryPipe setTransform failed to enable barrier"); 443 } 444 return mS3d.setTransform(param); 445} 446 447template <int CHAN> 448inline bool S3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) { 449 return mS3d.setTransform(param); 450} 451template <int CHAN> 452inline bool S3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args) 453{ 454 mS3Dfmt = utils::getS3DFormat(args.whf.format); 455 return mS3d.setSource(args); 456} 457template <int CHAN> 458inline void S3DPrimaryPipe<CHAN>::dump() const { 459 ALOGE("S3DPrimaryPipe Pipe fmt=%d", mS3Dfmt); 460 mS3d.dump(); 461} 462 463} // overlay 464 465#endif // OVERLAY_M3D_EXT_PIPE_H 466