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(); validRotMem53 bool valid() { return mem.valid(); } sizeRotMem54 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; setCurrBufReleaseFd(const int & fence)100 inline void setCurrBufReleaseFd(const int& fence) { 101 mMem.setCurrBufReleaseFd(fence); 102 } setPrevBufReleaseFd(const int & fence)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 markUnusedTop(const uint32_t & count)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(); getNumActiveSessions()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