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