Home | History | Annotate | Download | only in liboverlay
      1 /*
      2 * Copyright (c) 2011,2013 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_ROTATOR_H
     31 #define OVERlAY_ROTATOR_H
     32 
     33 #include <stdlib.h>
     34 
     35 #include "mdpWrapper.h"
     36 #include "overlayUtils.h"
     37 #include "overlayMem.h"
     38 
     39 namespace overlay {
     40 
     41 /*
     42    Manages the case where new rotator memory needs to be
     43    allocated, before previous is freed, due to resolution change etc. If we make
     44    rotator memory to be always max size, irrespctive of source resolution then
     45    we don't need this RotMem wrapper. The inner class is sufficient.
     46 */
     47 struct RotMem {
     48     // Max rotator buffers
     49     enum { ROT_NUM_BUFS = 2 };
     50     RotMem();
     51     ~RotMem();
     52     bool close();
     53     bool valid() { return mem.valid(); }
     54     uint32_t size() const { return mem.bufSz(); }
     55     void setCurrBufReleaseFd(const int& fence);
     56     void setPrevBufReleaseFd(const int& fence);
     57 
     58     // rotator data info dst offset
     59     uint32_t mRotOffset[ROT_NUM_BUFS];
     60     int mRelFence[ROT_NUM_BUFS];
     61     // current slot being used
     62     uint32_t mCurrIndex;
     63     OvMem mem;
     64 };
     65 
     66 class Rotator
     67 {
     68 public:
     69     enum { TYPE_MDP, TYPE_MDSS };
     70     virtual ~Rotator();
     71     virtual void setSource(const utils::Whf& wfh) = 0;
     72     virtual void setCrop(const utils::Dim& crop) = 0;
     73     virtual void setFlags(const utils::eMdpFlags& flags) = 0;
     74     virtual void setTransform(const utils::eTransform& rot) = 0;
     75     virtual bool commit() = 0;
     76     /* return true if the current rotator state is cached */
     77     virtual bool isRotCached(int fd, uint32_t offset) const;
     78     /* return true if current rotator config is same as the last round*/
     79     virtual bool rotConfChanged() const = 0;
     80     /* return true if the current rotator input buffer fd and offset
     81      * are same as the last round */
     82     virtual bool rotDataChanged(int fd, uint32_t offset) const;
     83     virtual void setDownscale(int ds) = 0;
     84     /* returns the src buffer of the rotator for the previous/current round,
     85      * depending on when it is called(before/after the queuebuffer)*/
     86     virtual int getSrcMemId() const = 0;
     87     //Mem id and offset should be retrieved only after rotator kickoff
     88     virtual int getDstMemId() const = 0;
     89     virtual uint32_t getSrcOffset() const = 0;
     90     virtual uint32_t getDstOffset() const = 0;
     91     //Destination width, height, format, position should be retrieved only after
     92     //rotator configuration is committed via commit API
     93     virtual uint32_t getDstFormat() const = 0;
     94     virtual utils::Whf getDstWhf() const = 0;
     95     virtual utils::Dim getDstDimensions() const = 0;
     96     virtual uint32_t getSessId() const = 0;
     97     virtual bool queueBuffer(int fd, uint32_t offset) = 0;
     98     virtual void dump() const = 0;
     99     virtual void getDump(char *buf, size_t len) const = 0;
    100     inline void setCurrBufReleaseFd(const int& fence) {
    101         mMem.setCurrBufReleaseFd(fence);
    102     }
    103     inline void setPrevBufReleaseFd(const int& fence) {
    104         mMem.setPrevBufReleaseFd(fence);
    105     }
    106     static Rotator *getRotator();
    107     /* Returns downscale by successfully applying constraints
    108      * Returns 0 if target doesnt support rotator downscaling
    109      * or if any of the constraints are not met
    110      */
    111     static int getDownscaleFactor(const int& srcW, const int& srcH,
    112             const int& dstW, const int& dstH, const uint32_t& mdpFormat,
    113             const bool& isInterlaced);
    114 
    115 protected:
    116     /* Rotator memory manager */
    117     RotMem mMem;
    118     Rotator();
    119     static uint32_t calcOutputBufSize(const utils::Whf& destWhf);
    120 
    121 private:
    122     bool mRotCacheDisabled;
    123     /*Returns rotator h/w type */
    124     static int getRotatorHwType();
    125     friend class RotMgr;
    126 };
    127 
    128 /*
    129 * MDP rot holds MDP's rotation related structures.
    130 *
    131 * */
    132 class MdpRot : public Rotator {
    133 public:
    134     virtual ~MdpRot();
    135     virtual void setSource(const utils::Whf& wfh);
    136     virtual void setCrop(const utils::Dim& crop);
    137     virtual void setFlags(const utils::eMdpFlags& flags);
    138     virtual void setTransform(const utils::eTransform& rot);
    139     virtual bool commit();
    140     virtual bool rotConfChanged() const;
    141     virtual void setDownscale(int ds);
    142     virtual int getSrcMemId() const;
    143     virtual int getDstMemId() const;
    144     virtual uint32_t getSrcOffset() const;
    145     virtual uint32_t getDstOffset() const;
    146     virtual uint32_t getDstFormat() const;
    147     virtual utils::Whf getDstWhf() const;
    148     virtual utils::Dim getDstDimensions() const;
    149     virtual uint32_t getSessId() const;
    150     virtual bool queueBuffer(int fd, uint32_t offset);
    151     virtual void dump() const;
    152     virtual void getDump(char *buf, size_t len) const;
    153 
    154 private:
    155     explicit MdpRot();
    156     bool init();
    157     bool close();
    158     void setRotations(uint32_t r);
    159     bool enabled () const;
    160     /* remap rot buffers */
    161     bool remap(uint32_t numbufs);
    162     bool open_i(uint32_t numbufs, uint32_t bufsz);
    163     /* Deferred transform calculations */
    164     void doTransform();
    165     /* reset underlying data, basically memset 0 */
    166     void reset();
    167     /* save mRotImgInfo to be last known good config*/
    168     void save();
    169     /* Calculates the rotator's o/p buffer size post the transform calcs and
    170      * knowing the o/p format depending on whether fastYuv is enabled or not */
    171     uint32_t calcOutputBufSize();
    172 
    173     /* Applies downscale by taking areas
    174      * Returns a log(downscale)
    175      * Constraints applied:
    176      * - downscale should be a power of 2
    177      * - Max downscale is 1/8
    178      */
    179     static int getDownscaleFactor(const int& srcW, const int& srcH,
    180             const int& dstW, const int& dstH, const uint32_t& mdpFormat,
    181             const bool& isInterlaced);
    182 
    183     /* rot info*/
    184     msm_rotator_img_info mRotImgInfo;
    185     /* Last saved rot info*/
    186     msm_rotator_img_info mLSRotImgInfo;
    187     /* rot data */
    188     msm_rotator_data_info mRotDataInfo;
    189     /* Orientation */
    190     utils::eTransform mOrientation;
    191     /* rotator fd */
    192     OvFD mFd;
    193 
    194     friend Rotator* Rotator::getRotator();
    195     friend int Rotator::getDownscaleFactor(const int& srcW, const int& srcH,
    196             const int& dstW, const int& dstH, const uint32_t& mdpFormat,
    197             const bool& isInterlaced);
    198 };
    199 
    200 /*
    201 +* MDSS Rot holds MDSS's rotation related structures.
    202 +*
    203 +* */
    204 class MdssRot : public Rotator {
    205 public:
    206     virtual ~MdssRot();
    207     virtual void setSource(const utils::Whf& wfh);
    208     virtual void setCrop(const utils::Dim& crop);
    209     virtual void setFlags(const utils::eMdpFlags& flags);
    210     virtual void setTransform(const utils::eTransform& rot);
    211     virtual bool commit();
    212     virtual bool rotConfChanged() const;
    213     virtual void setDownscale(int ds);
    214     virtual int getSrcMemId() const;
    215     virtual int getDstMemId() const;
    216     virtual uint32_t getSrcOffset() const;
    217     virtual uint32_t getDstOffset() const;
    218     virtual uint32_t getDstFormat() const;
    219     virtual utils::Whf getDstWhf() const;
    220     virtual utils::Dim getDstDimensions() const;
    221     virtual uint32_t getSessId() const;
    222     virtual bool queueBuffer(int fd, uint32_t offset);
    223     virtual void dump() const;
    224     virtual void getDump(char *buf, size_t len) const;
    225 
    226 private:
    227     explicit MdssRot();
    228     bool init();
    229     bool close();
    230     void setRotations(uint32_t r);
    231     bool enabled () const;
    232     /* remap rot buffers */
    233     bool remap(uint32_t numbufs);
    234     bool open_i(uint32_t numbufs, uint32_t bufsz);
    235     /* Deferred transform calculations */
    236     void doTransform();
    237     /* reset underlying data, basically memset 0 */
    238     void reset();
    239     /* save mRotInfo to be last known good config*/
    240     void save();
    241     /* Calculates the rotator's o/p buffer size post the transform calcs and
    242      * knowing the o/p format depending on whether fastYuv is enabled or not */
    243     uint32_t calcOutputBufSize();
    244     // Calculate the compressed o/p buffer size for BWC
    245     uint32_t calcCompressedBufSize(const utils::Whf& destWhf);
    246 
    247      /* Caller's responsibility to swap srcW, srcH if there is a 90 transform
    248       * Returns actual downscale (not a log value)
    249       * Constraints applied:
    250       * - downscale should be a power of 2
    251       * - Max downscale is 1/32
    252       * - Equal downscale is applied in both directions
    253       * - {srcW, srcH} mod downscale = 0
    254       * - Interlaced content is not supported
    255       */
    256     static int getDownscaleFactor(const int& srcW, const int& srcH,
    257             const int& dstW, const int& dstH, const uint32_t& mdpFormat,
    258             const bool& isInterlaced);
    259 
    260     static utils::Dim getFormatAdjustedCrop(const utils::Dim& crop,
    261             const uint32_t& mdpFormat, const bool& isInterlaced);
    262 
    263     static utils::Dim getDownscaleAdjustedCrop(const utils::Dim& crop,
    264             const uint32_t& downscale);
    265 
    266     /* MdssRot info structure */
    267     mdp_overlay mRotInfo;
    268     /* Last saved MdssRot info structure*/
    269     mdp_overlay mLSRotInfo;
    270     /* MdssRot data structure */
    271     msmfb_overlay_data mRotData;
    272     /* Orientation */
    273     utils::eTransform mOrientation;
    274     /* rotator fd */
    275     OvFD mFd;
    276     /* Enable/Disable Mdss Rot*/
    277     bool mEnabled;
    278     int mDownscale;
    279 
    280     friend Rotator* Rotator::getRotator();
    281     friend int Rotator::getDownscaleFactor(const int& srcW, const int& srcH,
    282             const int& dstW, const int& dstH, const uint32_t& mdpFormat,
    283             const bool& isInterlaced);
    284 };
    285 
    286 // Holder of rotator objects. Manages lifetimes
    287 class RotMgr {
    288 public:
    289     //Virtually we can support as many rotator sessions as possible, However
    290     // more number of rotator sessions leads to performance issues, so
    291     // restricting the max rotator session to 4
    292     enum { MAX_ROT_SESS = 4 };
    293 
    294     ~RotMgr();
    295     void configBegin();
    296     void configDone();
    297     overlay::Rotator *getNext();
    298     void clear(); //Removes all instances
    299     //Resets the usage of top count objects, making them available for reuse
    300     void markUnusedTop(const uint32_t& count) { mUseCount -= count; }
    301     /* Returns rot dump.
    302      * Expects a NULL terminated buffer of big enough size.
    303      */
    304     void getDump(char *buf, size_t len);
    305     int getRotDevFd();
    306     int getNumActiveSessions() { return mUseCount; }
    307 
    308     static RotMgr *getInstance();
    309 
    310 private:
    311     RotMgr();
    312     static RotMgr *sRotMgr;
    313 
    314     overlay::Rotator *mRot[MAX_ROT_SESS];
    315     uint32_t mUseCount;
    316     int mRotDevFd;
    317 };
    318 
    319 
    320 } // overlay
    321 
    322 #endif // OVERlAY_ROTATOR_H
    323