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#include "sync/sync.h"
39
40namespace overlay {
41
42/*
43   Manages the case where new rotator memory needs to be
44   allocated, before previous is freed, due to resolution change etc. If we make
45   rotator memory to be always max size, irrespctive of source resolution then
46   we don't need this RotMem wrapper. The inner class is sufficient.
47*/
48struct RotMem {
49    // Max rotator buffers
50    enum { ROT_NUM_BUFS = 2 };
51    RotMem();
52    ~RotMem();
53    bool close();
54    bool valid() { return mem.valid(); }
55    uint32_t size() const { return mem.bufSz(); }
56    void setReleaseFd(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
66class Rotator
67{
68public:
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    virtual void setDownscale(int ds) = 0;
77    //Mem id and offset should be retrieved only after rotator kickoff
78    virtual int getDstMemId() const = 0;
79    virtual uint32_t getDstOffset() const = 0;
80    //Destination width, height, format, position should be retrieved only after
81    //rotator configuration is committed via commit API
82    virtual uint32_t getDstFormat() const = 0;
83    virtual utils::Whf getDstWhf() const = 0;
84    virtual utils::Dim getDstDimensions() const = 0;
85    virtual uint32_t getSessId() const = 0;
86    virtual bool queueBuffer(int fd, uint32_t offset) = 0;
87    virtual void dump() const = 0;
88    virtual void getDump(char *buf, size_t len) const = 0;
89    void setReleaseFd(const int& fence) { mMem.setReleaseFd(fence); }
90    static Rotator *getRotator();
91
92protected:
93    /* Rotator memory manager */
94    RotMem mMem;
95    explicit Rotator() {}
96    static uint32_t calcOutputBufSize(const utils::Whf& destWhf);
97
98private:
99    /*Returns rotator h/w type */
100    static int getRotatorHwType();
101    friend class RotMgr;
102};
103
104/*
105* MDP rot holds MDP's rotation related structures.
106*
107* */
108class MdpRot : public Rotator {
109public:
110    virtual ~MdpRot();
111    virtual void setSource(const utils::Whf& wfh);
112    virtual void setCrop(const utils::Dim& crop);
113    virtual void setFlags(const utils::eMdpFlags& flags);
114    virtual void setTransform(const utils::eTransform& rot);
115    virtual bool commit();
116    virtual void setDownscale(int ds);
117    virtual int getDstMemId() const;
118    virtual uint32_t getDstOffset() const;
119    virtual uint32_t getDstFormat() const;
120    virtual utils::Whf getDstWhf() const;
121    virtual utils::Dim getDstDimensions() const;
122    virtual uint32_t getSessId() const;
123    virtual bool queueBuffer(int fd, uint32_t offset);
124    virtual void dump() const;
125    virtual void getDump(char *buf, size_t len) const;
126
127private:
128    explicit MdpRot();
129    bool init();
130    bool close();
131    void setRotations(uint32_t r);
132    bool enabled () const;
133    /* remap rot buffers */
134    bool remap(uint32_t numbufs);
135    bool open_i(uint32_t numbufs, uint32_t bufsz);
136    /* Deferred transform calculations */
137    void doTransform();
138    /* reset underlying data, basically memset 0 */
139    void reset();
140    /* return true if current rotator config is different
141     * than last known config */
142    bool rotConfChanged() const;
143    /* save mRotImgInfo to be last known good config*/
144    void save();
145    /* Calculates the rotator's o/p buffer size post the transform calcs and
146     * knowing the o/p format depending on whether fastYuv is enabled or not */
147    uint32_t calcOutputBufSize();
148
149    /* rot info*/
150    msm_rotator_img_info mRotImgInfo;
151    /* Last saved rot info*/
152    msm_rotator_img_info mLSRotImgInfo;
153    /* rot data */
154    msm_rotator_data_info mRotDataInfo;
155    /* Orientation */
156    utils::eTransform mOrientation;
157    /* rotator fd */
158    OvFD mFd;
159
160    friend Rotator* Rotator::getRotator();
161};
162
163/*
164+* MDSS Rot holds MDSS's rotation related structures.
165+*
166+* */
167class MdssRot : public Rotator {
168public:
169    virtual ~MdssRot();
170    virtual void setSource(const utils::Whf& wfh);
171    virtual void setCrop(const utils::Dim& crop);
172    virtual void setFlags(const utils::eMdpFlags& flags);
173    virtual void setTransform(const utils::eTransform& rot);
174    virtual bool commit();
175    virtual void setDownscale(int ds);
176    virtual int getDstMemId() const;
177    virtual uint32_t getDstOffset() const;
178    virtual uint32_t getDstFormat() const;
179    virtual utils::Whf getDstWhf() const;
180    virtual utils::Dim getDstDimensions() const;
181    virtual uint32_t getSessId() const;
182    virtual bool queueBuffer(int fd, uint32_t offset);
183    virtual void dump() const;
184    virtual void getDump(char *buf, size_t len) const;
185
186private:
187    explicit MdssRot();
188    bool init();
189    bool close();
190    void setRotations(uint32_t r);
191    bool enabled () const;
192    /* remap rot buffers */
193    bool remap(uint32_t numbufs);
194    bool open_i(uint32_t numbufs, uint32_t bufsz);
195    /* Deferred transform calculations */
196    void doTransform();
197    /* reset underlying data, basically memset 0 */
198    void reset();
199    /* Calculates the rotator's o/p buffer size post the transform calcs and
200     * knowing the o/p format depending on whether fastYuv is enabled or not */
201    uint32_t calcOutputBufSize();
202    // Calculate the compressed o/p buffer size for BWC
203    uint32_t calcCompressedBufSize(const utils::Whf& destWhf);
204
205    /* MdssRot info structure */
206    mdp_overlay   mRotInfo;
207    /* MdssRot data structure */
208    msmfb_overlay_data mRotData;
209    /* Orientation */
210    utils::eTransform mOrientation;
211    /* rotator fd */
212    OvFD mFd;
213    /* Enable/Disable Mdss Rot*/
214    bool mEnabled;
215
216    friend Rotator* Rotator::getRotator();
217};
218
219// Holder of rotator objects. Manages lifetimes
220class RotMgr {
221public:
222    //Virtually we can support as many rotator sessions as possible, However
223    // more number of rotator sessions leads to performance issues, so
224    // restricting the max rotator session to 4
225    enum { MAX_ROT_SESS = 4 };
226
227    ~RotMgr();
228    void configBegin();
229    void configDone();
230    overlay::Rotator *getNext();
231    void clear(); //Removes all instances
232    //Resets the usage of top count objects, making them available for reuse
233    void markUnusedTop(const uint32_t& count) { mUseCount -= count; }
234    /* Returns rot dump.
235     * Expects a NULL terminated buffer of big enough size.
236     */
237    void getDump(char *buf, size_t len);
238    int getRotDevFd();
239    int getNumActiveSessions() { return mUseCount; }
240
241    static RotMgr *getInstance();
242
243private:
244    RotMgr();
245    static RotMgr *sRotMgr;
246
247    overlay::Rotator *mRot[MAX_ROT_SESS];
248    uint32_t mUseCount;
249    int mRotDevFd;
250};
251
252
253} // overlay
254
255#endif // OVERlAY_ROTATOR_H
256