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    virtual int getDstMemId() const = 0;
78    virtual uint32_t getDstOffset() const = 0;
79    virtual uint32_t getDstFormat() const = 0;
80    virtual uint32_t getSessId() const = 0;
81    virtual bool queueBuffer(int fd, uint32_t offset) = 0;
82    virtual void dump() const = 0;
83    virtual void getDump(char *buf, size_t len) const = 0;
84    void setReleaseFd(const int& fence) { mMem.setReleaseFd(fence); }
85    static Rotator *getRotator();
86
87protected:
88    /* Rotator memory manager */
89    RotMem mMem;
90    explicit Rotator() {}
91    static uint32_t calcOutputBufSize(const utils::Whf& destWhf);
92
93private:
94    /*Returns rotator h/w type */
95    static int getRotatorHwType();
96    friend class RotMgr;
97};
98
99/*
100* MDP rot holds MDP's rotation related structures.
101*
102* */
103class MdpRot : public Rotator {
104public:
105    virtual ~MdpRot();
106    virtual void setSource(const utils::Whf& wfh);
107    virtual void setCrop(const utils::Dim& crop);
108    virtual void setFlags(const utils::eMdpFlags& flags);
109    virtual void setTransform(const utils::eTransform& rot);
110    virtual bool commit();
111    virtual void setDownscale(int ds);
112    virtual int getDstMemId() const;
113    virtual uint32_t getDstOffset() const;
114    virtual uint32_t getDstFormat() const;
115    virtual uint32_t getSessId() const;
116    virtual bool queueBuffer(int fd, uint32_t offset);
117    virtual void dump() const;
118    virtual void getDump(char *buf, size_t len) const;
119
120private:
121    explicit MdpRot();
122    bool init();
123    bool close();
124    void setRotations(uint32_t r);
125    bool enabled () const;
126    /* remap rot buffers */
127    bool remap(uint32_t numbufs);
128    bool open_i(uint32_t numbufs, uint32_t bufsz);
129    /* Deferred transform calculations */
130    void doTransform();
131    /* reset underlying data, basically memset 0 */
132    void reset();
133    /* return true if current rotator config is different
134     * than last known config */
135    bool rotConfChanged() const;
136    /* save mRotImgInfo to be last known good config*/
137    void save();
138    /* Calculates the rotator's o/p buffer size post the transform calcs and
139     * knowing the o/p format depending on whether fastYuv is enabled or not */
140    uint32_t calcOutputBufSize();
141
142    /* rot info*/
143    msm_rotator_img_info mRotImgInfo;
144    /* Last saved rot info*/
145    msm_rotator_img_info mLSRotImgInfo;
146    /* rot data */
147    msm_rotator_data_info mRotDataInfo;
148    /* Orientation */
149    utils::eTransform mOrientation;
150    /* rotator fd */
151    OvFD mFd;
152
153    friend Rotator* Rotator::getRotator();
154};
155
156/*
157+* MDSS Rot holds MDSS's rotation related structures.
158+*
159+* */
160class MdssRot : public Rotator {
161public:
162    virtual ~MdssRot();
163    virtual void setSource(const utils::Whf& wfh);
164    virtual void setCrop(const utils::Dim& crop);
165    virtual void setFlags(const utils::eMdpFlags& flags);
166    virtual void setTransform(const utils::eTransform& rot);
167    virtual bool commit();
168    virtual void setDownscale(int ds);
169    virtual int getDstMemId() const;
170    virtual uint32_t getDstOffset() const;
171    virtual uint32_t getDstFormat() const;
172    virtual uint32_t getSessId() const;
173    virtual bool queueBuffer(int fd, uint32_t offset);
174    virtual void dump() const;
175    virtual void getDump(char *buf, size_t len) const;
176
177private:
178    explicit MdssRot();
179    bool init();
180    bool close();
181    void setRotations(uint32_t r);
182    bool enabled () const;
183    /* remap rot buffers */
184    bool remap(uint32_t numbufs);
185    bool open_i(uint32_t numbufs, uint32_t bufsz);
186    /* Deferred transform calculations */
187    void doTransform();
188    /* reset underlying data, basically memset 0 */
189    void reset();
190    /* Calculates the rotator's o/p buffer size post the transform calcs and
191     * knowing the o/p format depending on whether fastYuv is enabled or not */
192    uint32_t calcOutputBufSize();
193    // Calculate the compressed o/p buffer size for BWC
194    uint32_t calcCompressedBufSize(const utils::Whf& destWhf);
195
196    /* MdssRot info structure */
197    mdp_overlay   mRotInfo;
198    /* MdssRot data structure */
199    msmfb_overlay_data mRotData;
200    /* Orientation */
201    utils::eTransform mOrientation;
202    /* rotator fd */
203    OvFD mFd;
204    /* Enable/Disable Mdss Rot*/
205    bool mEnabled;
206
207    friend Rotator* Rotator::getRotator();
208};
209
210// Holder of rotator objects. Manages lifetimes
211class RotMgr {
212public:
213    enum { MAX_ROT_SESS = 4 };
214
215    ~RotMgr();
216    void configBegin();
217    void configDone();
218    overlay::Rotator *getNext();
219    void clear(); //Removes all instances
220    //Resets the usage of top count objects, making them available for reuse
221    void markUnusedTop(const uint32_t& count) { mUseCount -= count; }
222    /* Returns rot dump.
223     * Expects a NULL terminated buffer of big enough size.
224     */
225    void getDump(char *buf, size_t len);
226    int getRotDevFd();
227    int getNumActiveSessions() { return mUseCount; }
228
229    static RotMgr *getInstance();
230
231private:
232    RotMgr();
233    static RotMgr *sRotMgr;
234
235    overlay::Rotator *mRot[MAX_ROT_SESS];
236    uint32_t mUseCount;
237    int mRotDevFd;
238};
239
240
241} // overlay
242
243#endif // OVERlAY_ROTATOR_H
244