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();
40    /* dtor close */
41    ~MdpCtrl();
42    /* init underlying device using fbnum */
43    bool init(uint32_t fbnum);
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    void setTransform(const utils::eTransform& orient);
61    /* given a dim and w/h, set overlay dim */
62    void setPosition(const utils::Dim& dim);
63    /* using user_data, sets/unsets roationvalue in mdp flags */
64    void setRotationFlags();
65    /* Performs downscale calculations */
66    void setDownscale(int dscale_factor);
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
74    /* returns session id */
75    int getPipeId() const;
76    /* returns the fd associated to ctrl*/
77    int getFd() const;
78    /* returns a copy ro dst rect dim */
79    utils::Dim getDstRectDim() const;
80    /* returns a copy to src rect dim */
81    utils::Dim getSrcRectDim() const;
82    /* setVisualParam */
83    bool setVisualParams(const MetaData_t& data);
84
85private:
86    /* Perform transformation calculations */
87    void doTransform();
88    void doDownscale();
89    /* get orient / user_data[0] */
90        int getOrient() const;
91    /* overlay get */
92    bool get();
93    /* returns flags from mdp structure */
94    int getFlags() const;
95    /* set flags to mdp structure */
96    void setFlags(int f);
97    /* set z order */
98    void setZ(utils::eZorder z);
99    /* set isFg flag */
100    void setIsFg(utils::eIsFg isFg);
101    /* return a copy of src whf*/
102    utils::Whf getSrcWhf() const;
103    /* set plane alpha */
104    void setPlaneAlpha(int planeAlpha);
105    /* set blending method */
106    void setBlending(overlay::utils::eBlending blending);
107
108    /* set src whf */
109    void setSrcWhf(const utils::Whf& whf);
110    /* set src/dst rect dim */
111    void setSrcRectDim(const utils::Dim d);
112    void setDstRectDim(const utils::Dim d);
113    /* returns user_data[0]*/
114    int getUserData() const;
115    /* sets user_data[0] */
116    void setUserData(int v);
117    /* return true if current overlay is different
118     * than last known good overlay */
119    bool ovChanged() const;
120    /* save mOVInfo to be last known good ov*/
121    void save();
122    /* restore last known good ov to be the current */
123    void restore();
124
125    utils::eTransform mOrientation; //Holds requested orientation
126    /* last good known ov info */
127    mdp_overlay   mLkgo;
128    /* Actual overlay mdp structure */
129    mdp_overlay   mOVInfo;
130    /* FD for the mdp fbnum */
131    OvFD          mFd;
132    int mDownscale;
133#ifdef USES_POST_PROCESSING
134    /* PP Compute Params */
135    struct compute_params mParams;
136    /* indicate if PP params have been changed */
137    bool mPPChanged;
138#endif
139};
140
141
142/* MDP 3D related ctrl */
143class MdpCtrl3D {
144public:
145    /* ctor reset data */
146    MdpCtrl3D();
147    /* calls MSMFB_OVERLAY_3D */
148    bool close();
149    /* set w/h. format is ignored*/
150    void setWh(const utils::Whf& whf);
151    /* set is_3d calls MSMFB_OVERLAY_3D */
152    bool useVirtualFB();
153    /* set fd to be used in ioctl */
154    void setFd(int fd);
155    /* dump */
156    void dump() const;
157private:
158    /* reset */
159    void reset();
160    /* actual MSM 3D info */
161    msmfb_overlay_3d m3DOVInfo;
162    /* FD for the mdp 3D */
163    OvFD mFd;
164};
165
166/* MDP data */
167class MdpData {
168public:
169    /* ctor reset data */
170    explicit MdpData();
171    /* dtor close*/
172    ~MdpData();
173    /* init FD */
174    bool init(uint32_t fbnum);
175    /* memset0 the underlying mdp object */
176    void reset();
177    /* close fd, and reset */
178    bool close();
179    /* set id of mdp data */
180    void setPipeId(int id);
181    /* return ses id of data */
182    int getPipeId() const;
183    /* get underlying fd*/
184    int getFd() const;
185    /* get memory_id */
186    int getSrcMemoryId() const;
187    /* calls wrapper play */
188    bool play(int fd, uint32_t offset);
189    /* dump state of the object */
190    void dump() const;
191    /* Return the dump in the specified buffer */
192    void getDump(char *buf, size_t len);
193
194private:
195
196    /* actual overlay mdp data */
197    msmfb_overlay_data mOvData;
198    /* fd to mdp fbnum */
199    OvFD mFd;
200};
201
202//--------------Inlines---------------------------------
203
204/////   MdpCtrl  //////
205
206inline MdpCtrl::MdpCtrl() {
207    reset();
208}
209
210inline MdpCtrl::~MdpCtrl() {
211    close();
212}
213
214inline int MdpCtrl::getOrient() const {
215    return getUserData();
216}
217
218inline int MdpCtrl::getPipeId() const {
219    return mOVInfo.id;
220}
221
222inline int MdpCtrl::getFd() const {
223    return mFd.getFD();
224}
225
226inline int MdpCtrl::getFlags() const {
227    return mOVInfo.flags;
228}
229
230inline void MdpCtrl::setFlags(int f) {
231    mOVInfo.flags = f;
232}
233
234inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
235    mOVInfo.z_order = z;
236}
237
238inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
239    mOVInfo.is_fg = isFg;
240}
241
242inline void MdpCtrl::setDownscale(int dscale) {
243    mDownscale = dscale;
244}
245
246inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
247    mOVInfo.alpha = planeAlpha;
248}
249
250inline void MdpCtrl::setBlending(overlay::utils::eBlending blending) {
251#ifndef MDSS_TARGET
252    switch((int) blending) {
253    case utils::OVERLAY_BLENDING_OPAQUE:
254        mOVInfo.blend_op = BLEND_OP_OPAQUE;
255        break;
256    case utils::OVERLAY_BLENDING_PREMULT:
257        mOVInfo.blend_op = BLEND_OP_PREMULTIPLIED;
258        break;
259    case utils::OVERLAY_BLENDING_COVERAGE:
260    default:
261        mOVInfo.blend_op = BLEND_OP_COVERAGE;
262    }
263#endif
264}
265
266inline bool MdpCtrl::ovChanged() const {
267#ifdef USES_POST_PROCESSING
268    // Some pp params are stored as pointer address,
269    // so can't compare their content directly.
270    if (mPPChanged) {
271        return true;
272    }
273#endif
274    // 0 means same
275    if(0 == ::memcmp(&mOVInfo, &mLkgo, sizeof (mdp_overlay))) {
276        return false;
277    }
278    return true;
279}
280
281inline void MdpCtrl::save() {
282    if(static_cast<ssize_t>(mOVInfo.id) == MSMFB_NEW_REQUEST) {
283        ALOGE("MdpCtrl current ov has id -1, will not save");
284        return;
285    }
286    mLkgo = mOVInfo;
287}
288
289inline void MdpCtrl::restore() {
290    if(static_cast<ssize_t>(mLkgo.id) == MSMFB_NEW_REQUEST) {
291        ALOGE("MdpCtrl Lkgo ov has id -1, will not restore");
292        return;
293    }
294    mOVInfo = mLkgo;
295}
296
297inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
298    return utils::Whf(  mOVInfo.src.width,
299                        mOVInfo.src.height,
300                        mOVInfo.src.format);
301}
302
303inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
304    mOVInfo.src.width  = whf.w;
305    mOVInfo.src.height = whf.h;
306    mOVInfo.src.format = whf.format;
307}
308
309inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
310    return utils::Dim(  mOVInfo.src_rect.x,
311                        mOVInfo.src_rect.y,
312                        mOVInfo.src_rect.w,
313                        mOVInfo.src_rect.h);
314}
315
316inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
317    mOVInfo.src_rect.x = d.x;
318    mOVInfo.src_rect.y = d.y;
319    mOVInfo.src_rect.w = d.w;
320    mOVInfo.src_rect.h = d.h;
321}
322
323inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
324    return utils::Dim(  mOVInfo.dst_rect.x,
325                        mOVInfo.dst_rect.y,
326                        mOVInfo.dst_rect.w,
327                        mOVInfo.dst_rect.h);
328}
329
330inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) {
331    mOVInfo.dst_rect.x = d.x;
332    mOVInfo.dst_rect.y = d.y;
333    mOVInfo.dst_rect.w = d.w;
334    mOVInfo.dst_rect.h = d.h;
335}
336
337inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }
338
339inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }
340
341inline void MdpCtrl::setRotationFlags() {
342    const int u = getUserData();
343    if (u & MDP_ROT_90)
344        mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
345}
346
347///////    MdpCtrl3D //////
348
349inline MdpCtrl3D::MdpCtrl3D() { reset(); }
350inline bool MdpCtrl3D::close() {
351    if (m3DOVInfo.is_3d) {
352        m3DOVInfo.is_3d = 0;
353        if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
354            ALOGE("MdpCtrl3D close failed set3D with 0");
355            return false;
356        }
357    }
358    reset();
359    return true;
360}
361inline void MdpCtrl3D::reset() {
362    utils::memset0(m3DOVInfo);
363}
364
365inline void MdpCtrl3D::setFd(int fd) {
366    mFd.copy(fd);
367    OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid");
368}
369
370inline void MdpCtrl3D::setWh(const utils::Whf& whf) {
371    // ignore fmt. Needed for useVirtualFB callflow
372    m3DOVInfo.width = whf.w;
373    m3DOVInfo.height = whf.h;
374}
375
376inline bool MdpCtrl3D::useVirtualFB() {
377    if(!m3DOVInfo.is_3d) {
378        m3DOVInfo.is_3d = 1;
379        if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
380            ALOGE("MdpCtrl3D close failed set3D with 0");
381            return false;
382        }
383    }
384    return true;
385}
386
387///////    MdpData   //////
388
389inline MdpData::MdpData() { reset(); }
390
391inline MdpData::~MdpData() { close(); }
392
393inline bool MdpData::init(uint32_t fbnum) {
394    // FD init
395    if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
396        ALOGE("Ctrl failed to init fbnum=%d", fbnum);
397        return false;
398    }
399    return true;
400}
401
402inline void MdpData::reset() {
403    overlay::utils::memset0(mOvData);
404    mOvData.data.memory_id = -1;
405}
406
407inline bool MdpData::close() {
408    reset();
409    return mFd.close();
410}
411
412inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }
413
414inline void MdpData::setPipeId(int id) { mOvData.id = id; }
415
416inline int MdpData::getPipeId() const { return mOvData.id; }
417
418inline int MdpData::getFd() const { return mFd.getFD(); }
419
420inline bool MdpData::play(int fd, uint32_t offset) {
421    mOvData.data.memory_id = fd;
422    mOvData.data.offset = offset;
423    if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
424        ALOGE("MdpData failed to play");
425        dump();
426        return false;
427    }
428    return true;
429}
430
431} // overlay
432
433#endif // OVERLAY_MDP_H
434