1/*
2* Copyright (C) 2008 The Android Open Source Project
3* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
4*
5* Licensed under the Apache License, Version 2.0 (the "License");
6* you may not use this file except in compliance with the License.
7* You may obtain a copy of the License at
8*
9*      http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS,
13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14* See the License for the specific language governing permissions and
15* limitations under the License.
16*/
17
18#ifndef OVERLAY_MDP_H
19#define OVERLAY_MDP_H
20
21#include <linux/msm_mdp.h>
22
23#include "overlayUtils.h"
24#include "mdpWrapper.h"
25#include "qdMetaData.h"
26#ifdef USES_POST_PROCESSING
27#include "lib-postproc.h"
28#endif
29
30namespace overlay{
31
32/*
33* Mdp Ctrl holds corresponding fd and MDP related struct.
34* It is simple wrapper to MDP services
35* */
36class MdpCtrl {
37public:
38    /* ctor reset */
39    explicit MdpCtrl(const int& dpy);
40    /* dtor close */
41    ~MdpCtrl();
42    /* init underlying device using fbnum for dpy */
43    bool init(const int& dpy);
44    /* unset overlay, reset and close fd */
45    bool close();
46    /* reset and set ov id to -1 / MSMFB_NEW_REQUEST */
47    void reset();
48    /* calls overlay set
49     * Set would always consult last good known ov instance.
50     * Only if it is different, set would actually exectue ioctl.
51     * On a sucess ioctl. last good known ov instance is updated */
52    bool set();
53    /* Sets the source total width, height, format */
54    void setSource(const utils::PipeArgs& pargs);
55    /*
56     * Sets ROI, the unpadded region, for source buffer.
57     * Dim - ROI dimensions.
58     */
59    void setCrop(const utils::Dim& d);
60    /* set color for mdp pipe */
61    void setColor(const uint32_t color);
62    void setTransform(const utils::eTransform& orient);
63    /* given a dim and w/h, set overlay dim */
64    void setPosition(const utils::Dim& dim);
65    /* using user_data, sets/unsets roationvalue in mdp flags */
66    void setRotationFlags();
67    /* Update the src format with rotator's dest*/
68    void updateSrcFormat(const uint32_t& rotDstFormat);
69    /* dump state of the object */
70    void dump() const;
71    /* Return the dump in the specified buffer */
72    void getDump(char *buf, size_t len);
73    /* returns session id */
74    int getPipeId() const;
75    /* returns the fd associated to ctrl*/
76    int getFd() const;
77    /* returns a copy ro dst rect dim */
78    utils::Dim getDstRectDim() const;
79    /* returns a copy to src rect dim */
80    utils::Dim getSrcRectDim() const;
81    /* return pipe priority */
82    uint8_t getPriority() const;
83    /* setVisualParam */
84    bool setVisualParams(const MetaData_t& data);
85    /* sets pipe type RGB/DMA/VG */
86    void setPipeType(const utils::eMdpPipeType& pType);
87
88    static bool validateAndSet(MdpCtrl* mdpCtrlArray[], const int& count,
89            const int& fbFd);
90private:
91    /* Perform transformation calculations */
92    void doTransform();
93    void doDownscale();
94    /* get orient / user_data[0] */
95    int getOrient() const;
96    /* returns flags from mdp structure */
97    int getFlags() const;
98    /* set flags to mdp structure */
99    void setFlags(int f);
100    /* set z order */
101    void setZ(utils::eZorder z);
102    /* set isFg flag */
103    void setIsFg(utils::eIsFg isFg);
104    /* return a copy of src whf*/
105    utils::Whf getSrcWhf() const;
106    /* set plane alpha */
107    void setPlaneAlpha(int planeAlpha);
108    /* set blending method */
109    void setBlending(overlay::utils::eBlending blending);
110
111    /* set src whf */
112    void setSrcWhf(const utils::Whf& whf);
113    /* set src/dst rect dim */
114    void setSrcRectDim(const utils::Dim d);
115    void setDstRectDim(const utils::Dim d);
116    /* returns user_data[0]*/
117    int getUserData() const;
118    /* sets user_data[0] */
119    void setUserData(int v);
120
121    utils::eTransform mOrientation; //Holds requested orientation
122    /* Actual overlay mdp structure */
123    mdp_overlay   mOVInfo;
124    /* FD for the mdp fbnum */
125    OvFD          mFd;
126    int mDpy;
127
128#ifdef USES_POST_PROCESSING
129    /* PP Compute Params */
130    struct compute_params mParams;
131#endif
132};
133
134/* MDP data */
135class MdpData {
136public:
137    /* ctor reset data */
138    explicit MdpData(const int& dpy);
139    /* dtor close*/
140    ~MdpData();
141    /* init FD */
142    bool init(const int& dpy);
143    /* memset0 the underlying mdp object */
144    void reset();
145    /* close fd, and reset */
146    bool close();
147    /* set id of mdp data */
148    void setPipeId(int id);
149    /* return ses id of data */
150    int getPipeId() const;
151    /* get underlying fd*/
152    int getFd() const;
153    /* get memory_id */
154    int getSrcMemoryId() const;
155    /* calls wrapper play */
156    bool play(int fd, uint32_t offset);
157    /* dump state of the object */
158    void dump() const;
159    /* Return the dump in the specified buffer */
160    void getDump(char *buf, size_t len);
161
162private:
163
164    /* actual overlay mdp data */
165    msmfb_overlay_data mOvData;
166    /* fd to mdp fbnum */
167    OvFD mFd;
168};
169
170//--------------Inlines---------------------------------
171
172/////   MdpCtrl  //////
173
174inline MdpCtrl::MdpCtrl(const int& dpy) {
175    reset();
176    init(dpy);
177}
178
179inline MdpCtrl::~MdpCtrl() {
180    close();
181}
182
183inline int MdpCtrl::getOrient() const {
184    return getUserData();
185}
186
187inline int MdpCtrl::getPipeId() const {
188    return mOVInfo.id;
189}
190
191inline int MdpCtrl::getFd() const {
192    return mFd.getFD();
193}
194
195inline int MdpCtrl::getFlags() const {
196    return mOVInfo.flags;
197}
198
199inline void MdpCtrl::setFlags(int f) {
200    mOVInfo.flags = f;
201}
202
203inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
204    mOVInfo.z_order = z;
205}
206
207inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
208    mOVInfo.is_fg = isFg;
209}
210
211inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
212    mOVInfo.alpha = planeAlpha;
213}
214
215inline void MdpCtrl::setBlending(overlay::utils::eBlending blending) {
216    switch((int) blending) {
217    case utils::OVERLAY_BLENDING_OPAQUE:
218        mOVInfo.blend_op = BLEND_OP_OPAQUE;
219        break;
220    case utils::OVERLAY_BLENDING_PREMULT:
221        mOVInfo.blend_op = BLEND_OP_PREMULTIPLIED;
222        break;
223    case utils::OVERLAY_BLENDING_COVERAGE:
224    default:
225        mOVInfo.blend_op = BLEND_OP_COVERAGE;
226    }
227}
228
229inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
230    return utils::Whf(  mOVInfo.src.width,
231                        mOVInfo.src.height,
232                        mOVInfo.src.format);
233}
234
235inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
236    mOVInfo.src.width  = whf.w;
237    mOVInfo.src.height = whf.h;
238    mOVInfo.src.format = whf.format;
239}
240
241inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
242    return utils::Dim(  mOVInfo.src_rect.x,
243                        mOVInfo.src_rect.y,
244                        mOVInfo.src_rect.w,
245                        mOVInfo.src_rect.h);
246}
247
248inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
249    mOVInfo.src_rect.x = d.x;
250    mOVInfo.src_rect.y = d.y;
251    mOVInfo.src_rect.w = d.w;
252    mOVInfo.src_rect.h = d.h;
253}
254
255inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
256    return utils::Dim(  mOVInfo.dst_rect.x,
257                        mOVInfo.dst_rect.y,
258                        mOVInfo.dst_rect.w,
259                        mOVInfo.dst_rect.h);
260}
261
262inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) {
263    mOVInfo.dst_rect.x = d.x;
264    mOVInfo.dst_rect.y = d.y;
265    mOVInfo.dst_rect.w = d.w;
266    mOVInfo.dst_rect.h = d.h;
267}
268
269inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }
270
271inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }
272
273inline void MdpCtrl::setRotationFlags() {
274    const int u = getUserData();
275    if (u & MDP_ROT_90)
276        mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
277}
278
279inline uint8_t MdpCtrl::getPriority() const {
280    return mOVInfo.priority;
281}
282
283///////    MdpData   //////
284
285inline MdpData::MdpData(const int& dpy) {
286    reset();
287    init(dpy);
288}
289
290inline MdpData::~MdpData() { close(); }
291
292inline void MdpData::reset() {
293    overlay::utils::memset0(mOvData);
294    mOvData.data.memory_id = -1;
295}
296
297inline bool MdpData::close() {
298    reset();
299    return mFd.close();
300}
301
302inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }
303
304inline void MdpData::setPipeId(int id) { mOvData.id = id; }
305
306inline int MdpData::getPipeId() const { return mOvData.id; }
307
308inline int MdpData::getFd() const { return mFd.getFD(); }
309
310inline bool MdpData::play(int fd, uint32_t offset) {
311    mOvData.data.memory_id = fd;
312    mOvData.data.offset = offset;
313    if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
314        ALOGE("MdpData failed to play");
315        dump();
316        return false;
317    }
318    return true;
319}
320
321} // overlay
322
323#endif // OVERLAY_MDP_H
324