Home | History | Annotate | Download | only in pipes
      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