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 
30 namespace overlay{
31 
32 /*
33 * Mdp Ctrl holds corresponding fd and MDP related struct.
34 * It is simple wrapper to MDP services
35 * */
36 class MdpCtrl {
37 public:
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     /* Performs downscale calculations */
68     void setDownscale(int dscale_factor);
69     /* Update the src format with rotator's dest*/
70     void updateSrcFormat(const uint32_t& rotDstFormat);
71     /* dump state of the object */
72     void dump() const;
73     /* Return the dump in the specified buffer */
74     void getDump(char *buf, size_t len);
75     /* returns session id */
76     int getPipeId() const;
77     /* returns the fd associated to ctrl*/
78     int getFd() const;
79     /* returns a copy ro dst rect dim */
80     utils::Dim getDstRectDim() const;
81     /* returns a copy to src rect dim */
82     utils::Dim getSrcRectDim() const;
83     /* return pipe priority */
84     uint8_t getPriority() const;
85     /* setVisualParam */
86     bool setVisualParams(const MetaData_t& data);
87 
88     static bool validateAndSet(MdpCtrl* mdpCtrlArray[], const int& count,
89             const int& fbFd);
90 private:
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 mDownscale;
127     int mDpy;
128 
129 #ifdef USES_POST_PROCESSING
130     /* PP Compute Params */
131     struct compute_params mParams;
132 #endif
133 };
134 
135 
136 /* MDP 3D related ctrl */
137 class MdpCtrl3D {
138 public:
139     /* ctor reset data */
140     MdpCtrl3D();
141     /* calls MSMFB_OVERLAY_3D */
142     bool close();
143     /* set w/h. format is ignored*/
144     void setWh(const utils::Whf& whf);
145     /* set is_3d calls MSMFB_OVERLAY_3D */
146     bool useVirtualFB();
147     /* set fd to be used in ioctl */
148     void setFd(int fd);
149     /* dump */
150     void dump() const;
151 private:
152     /* reset */
153     void reset();
154     /* actual MSM 3D info */
155     msmfb_overlay_3d m3DOVInfo;
156     /* FD for the mdp 3D */
157     OvFD mFd;
158 };
159 
160 /* MDP data */
161 class MdpData {
162 public:
163     /* ctor reset data */
164     explicit MdpData(const int& dpy);
165     /* dtor close*/
166     ~MdpData();
167     /* init FD */
168     bool init(const int& dpy);
169     /* memset0 the underlying mdp object */
170     void reset();
171     /* close fd, and reset */
172     bool close();
173     /* set id of mdp data */
174     void setPipeId(int id);
175     /* return ses id of data */
176     int getPipeId() const;
177     /* get underlying fd*/
178     int getFd() const;
179     /* get memory_id */
180     int getSrcMemoryId() const;
181     /* calls wrapper play */
182     bool play(int fd, uint32_t offset);
183     /* dump state of the object */
184     void dump() const;
185     /* Return the dump in the specified buffer */
186     void getDump(char *buf, size_t len);
187 
188 private:
189 
190     /* actual overlay mdp data */
191     msmfb_overlay_data mOvData;
192     /* fd to mdp fbnum */
193     OvFD mFd;
194 };
195 
196 //--------------Inlines---------------------------------
197 
198 /////   MdpCtrl  //////
199 
MdpCtrl(const int & dpy)200 inline MdpCtrl::MdpCtrl(const int& dpy) {
201     reset();
202     init(dpy);
203 }
204 
~MdpCtrl()205 inline MdpCtrl::~MdpCtrl() {
206     close();
207 }
208 
getOrient()209 inline int MdpCtrl::getOrient() const {
210     return getUserData();
211 }
212 
getPipeId()213 inline int MdpCtrl::getPipeId() const {
214     return mOVInfo.id;
215 }
216 
getFd()217 inline int MdpCtrl::getFd() const {
218     return mFd.getFD();
219 }
220 
getFlags()221 inline int MdpCtrl::getFlags() const {
222     return mOVInfo.flags;
223 }
224 
setFlags(int f)225 inline void MdpCtrl::setFlags(int f) {
226     mOVInfo.flags = f;
227 }
228 
setZ(overlay::utils::eZorder z)229 inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
230     mOVInfo.z_order = z;
231 }
232 
setIsFg(overlay::utils::eIsFg isFg)233 inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
234     mOVInfo.is_fg = isFg;
235 }
236 
setDownscale(int dscale)237 inline void MdpCtrl::setDownscale(int dscale) {
238     mDownscale = dscale;
239 }
240 
setPlaneAlpha(int planeAlpha)241 inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
242     mOVInfo.alpha = planeAlpha;
243 }
244 
setBlending(overlay::utils::eBlending blending)245 inline void MdpCtrl::setBlending(overlay::utils::eBlending blending) {
246     switch((int) blending) {
247     case utils::OVERLAY_BLENDING_OPAQUE:
248         mOVInfo.blend_op = BLEND_OP_OPAQUE;
249         break;
250     case utils::OVERLAY_BLENDING_PREMULT:
251         mOVInfo.blend_op = BLEND_OP_PREMULTIPLIED;
252         break;
253     case utils::OVERLAY_BLENDING_COVERAGE:
254     default:
255         mOVInfo.blend_op = BLEND_OP_COVERAGE;
256     }
257 }
258 
getSrcWhf()259 inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
260     return utils::Whf(  mOVInfo.src.width,
261                         mOVInfo.src.height,
262                         mOVInfo.src.format);
263 }
264 
setSrcWhf(const overlay::utils::Whf & whf)265 inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
266     mOVInfo.src.width  = whf.w;
267     mOVInfo.src.height = whf.h;
268     mOVInfo.src.format = whf.format;
269 }
270 
getSrcRectDim()271 inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
272     return utils::Dim(  mOVInfo.src_rect.x,
273                         mOVInfo.src_rect.y,
274                         mOVInfo.src_rect.w,
275                         mOVInfo.src_rect.h);
276 }
277 
setSrcRectDim(const overlay::utils::Dim d)278 inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
279     mOVInfo.src_rect.x = d.x;
280     mOVInfo.src_rect.y = d.y;
281     mOVInfo.src_rect.w = d.w;
282     mOVInfo.src_rect.h = d.h;
283 }
284 
getDstRectDim()285 inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
286     return utils::Dim(  mOVInfo.dst_rect.x,
287                         mOVInfo.dst_rect.y,
288                         mOVInfo.dst_rect.w,
289                         mOVInfo.dst_rect.h);
290 }
291 
setDstRectDim(const overlay::utils::Dim d)292 inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) {
293     mOVInfo.dst_rect.x = d.x;
294     mOVInfo.dst_rect.y = d.y;
295     mOVInfo.dst_rect.w = d.w;
296     mOVInfo.dst_rect.h = d.h;
297 }
298 
getUserData()299 inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }
300 
setUserData(int v)301 inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }
302 
setRotationFlags()303 inline void MdpCtrl::setRotationFlags() {
304     const int u = getUserData();
305     if (u & MDP_ROT_90)
306         mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
307 }
308 
getPriority()309 inline uint8_t MdpCtrl::getPriority() const {
310     return mOVInfo.priority;
311 }
312 
313 ///////    MdpCtrl3D //////
314 
MdpCtrl3D()315 inline MdpCtrl3D::MdpCtrl3D() { reset(); }
close()316 inline bool MdpCtrl3D::close() {
317     if (m3DOVInfo.is_3d) {
318         m3DOVInfo.is_3d = 0;
319         if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
320             ALOGE("MdpCtrl3D close failed set3D with 0");
321             return false;
322         }
323     }
324     reset();
325     return true;
326 }
reset()327 inline void MdpCtrl3D::reset() {
328     utils::memset0(m3DOVInfo);
329 }
330 
setFd(int fd)331 inline void MdpCtrl3D::setFd(int fd) {
332     mFd.copy(fd);
333     OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid");
334 }
335 
setWh(const utils::Whf & whf)336 inline void MdpCtrl3D::setWh(const utils::Whf& whf) {
337     // ignore fmt. Needed for useVirtualFB callflow
338     m3DOVInfo.width = whf.w;
339     m3DOVInfo.height = whf.h;
340 }
341 
useVirtualFB()342 inline bool MdpCtrl3D::useVirtualFB() {
343     if(!m3DOVInfo.is_3d) {
344         m3DOVInfo.is_3d = 1;
345         if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
346             ALOGE("MdpCtrl3D close failed set3D with 0");
347             return false;
348         }
349     }
350     return true;
351 }
352 
353 ///////    MdpData   //////
354 
MdpData(const int & dpy)355 inline MdpData::MdpData(const int& dpy) {
356     reset();
357     init(dpy);
358 }
359 
~MdpData()360 inline MdpData::~MdpData() { close(); }
361 
reset()362 inline void MdpData::reset() {
363     overlay::utils::memset0(mOvData);
364     mOvData.data.memory_id = -1;
365 }
366 
close()367 inline bool MdpData::close() {
368     reset();
369     return mFd.close();
370 }
371 
getSrcMemoryId()372 inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }
373 
setPipeId(int id)374 inline void MdpData::setPipeId(int id) { mOvData.id = id; }
375 
getPipeId()376 inline int MdpData::getPipeId() const { return mOvData.id; }
377 
getFd()378 inline int MdpData::getFd() const { return mFd.getFD(); }
379 
play(int fd,uint32_t offset)380 inline bool MdpData::play(int fd, uint32_t offset) {
381     mOvData.data.memory_id = fd;
382     mOvData.data.offset = offset;
383     if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
384         ALOGE("MdpData failed to play");
385         dump();
386         return false;
387     }
388     return true;
389 }
390 
391 } // overlay
392 
393 #endif // OVERLAY_MDP_H
394