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 36 namespace 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 */ 47 template <int CHAN> 48 class M3DExtPipe : utils::NoCopy { 49 public: 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; 62 private: 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 */ 77 template <int CHAN> 78 class M3DPrimaryPipe : utils::NoCopy { 79 public: 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; 92 private: 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 */ 107 template <int CHAN> 108 class S3DExtPipe : utils::NoCopy { 109 public: 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; 122 private: 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 */ 137 template <int CHAN> 138 class S3DPrimaryPipe : utils::NoCopy { 139 public: 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; 152 private: 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 //////////////////////////// 167 template <int CHAN> 168 inline M3DExtPipe<CHAN>::M3DExtPipe() : mM3Dfmt(0) {} 169 template <int CHAN> 170 inline M3DExtPipe<CHAN>::~M3DExtPipe() { close(); } 171 template <int CHAN> 172 inline 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 } 180 template <int CHAN> 181 inline bool M3DExtPipe<CHAN>::close() { 182 return mM3d.close(); 183 } 184 template <int CHAN> 185 inline bool M3DExtPipe<CHAN>::commit() { return mM3d.commit(); } 186 template <int CHAN> 187 inline bool M3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 188 return mM3d.queueBuffer(fd, offset); 189 } 190 template <int CHAN> 191 inline 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 200 template <int CHAN> 201 inline 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 } 216 template <int CHAN> 217 inline bool M3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) { 218 return mM3d.setTransform(param); 219 } 220 template <int CHAN> 221 inline 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 } 228 template <int CHAN> 229 inline void M3DExtPipe<CHAN>::dump() const { 230 ALOGE("M3DExtPipe Pipe fmt=%d", mM3Dfmt); 231 mM3d.dump(); 232 } 233 234 235 ///////////// M3DPrimary Pipe //////////////////////////// 236 template <int CHAN> 237 inline M3DPrimaryPipe<CHAN>::M3DPrimaryPipe() : mM3Dfmt(0) {} 238 template <int CHAN> 239 inline M3DPrimaryPipe<CHAN>::~M3DPrimaryPipe() { close(); } 240 template <int CHAN> 241 inline 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 } 249 template <int CHAN> 250 inline bool M3DPrimaryPipe<CHAN>::close() { 251 return mM3d.close(); 252 } 253 template <int CHAN> 254 inline bool M3DPrimaryPipe<CHAN>::commit() { return mM3d.commit(); } 255 template <int CHAN> 256 inline bool M3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 257 return mM3d.queueBuffer(fd, offset); 258 } 259 template <int CHAN> 260 inline 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 } 268 template <int CHAN> 269 inline bool M3DPrimaryPipe<CHAN>::setPosition(const utils::Dim& d) { 270 return mM3d.setPosition(d); 271 } 272 template <int CHAN> 273 inline bool M3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) { 274 return mM3d.setTransform(param); 275 } 276 template <int CHAN> 277 inline 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 } 284 template <int CHAN> 285 inline void M3DPrimaryPipe<CHAN>::dump() const { 286 ALOGE("M3DPrimaryPipe Pipe fmt=%d", mM3Dfmt); 287 mM3d.dump(); 288 } 289 290 ///////////// S3DExt Pipe //////////////////////////////// 291 template <int CHAN> 292 inline S3DExtPipe<CHAN>::S3DExtPipe() : mS3Dfmt(0) {} 293 template <int CHAN> 294 inline S3DExtPipe<CHAN>::~S3DExtPipe() { close(); } 295 template <int CHAN> 296 inline 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 } 304 template <int CHAN> 305 inline bool S3DExtPipe<CHAN>::close() { 306 if(!utils::send3DInfoPacket(0)) { 307 ALOGE("S3DExtPipe close failed send3D info packet"); 308 } 309 return mS3d.close(); 310 } 311 template <int CHAN> 312 inline bool S3DExtPipe<CHAN>::commit() { return mS3d.commit(); } 313 template <int CHAN> 314 inline bool S3DExtPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 315 return mS3d.queueBuffer(fd, offset); 316 } 317 template <int CHAN> 318 inline 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 } 326 template <int CHAN> 327 inline 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 } 339 template <int CHAN> 340 inline bool S3DExtPipe<CHAN>::setTransform(const utils::eTransform& param) { 341 return mS3d.setTransform(param); 342 } 343 template <int CHAN> 344 inline bool S3DExtPipe<CHAN>::setSource(const utils::PipeArgs& args) { 345 mS3Dfmt = utils::getS3DFormat(args.whf.format); 346 return mS3d.setSource(args); 347 } 348 template <int CHAN> 349 inline void S3DExtPipe<CHAN>::dump() const { 350 ALOGE("S3DExtPipe Pipe fmt=%d", mS3Dfmt); 351 mS3d.dump(); 352 } 353 354 ///////////// S3DPrimary Pipe //////////////////////////// 355 template <int CHAN> 356 inline S3DPrimaryPipe<CHAN>::S3DPrimaryPipe() : mS3Dfmt(0) {} 357 template <int CHAN> 358 inline S3DPrimaryPipe<CHAN>::~S3DPrimaryPipe() { close(); } 359 template <int CHAN> 360 inline 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 } 370 template <int CHAN> 371 inline 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 379 template <int CHAN> 380 inline 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 } 388 template <int CHAN> 389 inline bool S3DPrimaryPipe<CHAN>::queueBuffer(int fd, uint32_t offset) { 390 return mS3d.queueBuffer(fd, offset); 391 } 392 template <int CHAN> 393 inline 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 } 401 template <int CHAN> 402 inline 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 */ 428 template <> 429 inline 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 447 template <int CHAN> 448 inline bool S3DPrimaryPipe<CHAN>::setTransform(const utils::eTransform& param) { 449 return mS3d.setTransform(param); 450 } 451 template <int CHAN> 452 inline bool S3DPrimaryPipe<CHAN>::setSource(const utils::PipeArgs& args) 453 { 454 mS3Dfmt = utils::getS3DFormat(args.whf.format); 455 return mS3d.setSource(args); 456 } 457 template <int CHAN> 458 inline 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