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 
85 private:
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 */
143 class MdpCtrl3D {
144 public:
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;
157 private:
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 */
167 class MdpData {
168 public:
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 
194 private:
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 
MdpCtrl()206 inline MdpCtrl::MdpCtrl() {
207     reset();
208 }
209 
~MdpCtrl()210 inline MdpCtrl::~MdpCtrl() {
211     close();
212 }
213 
getOrient()214 inline int MdpCtrl::getOrient() const {
215     return getUserData();
216 }
217 
getPipeId()218 inline int MdpCtrl::getPipeId() const {
219     return mOVInfo.id;
220 }
221 
getFd()222 inline int MdpCtrl::getFd() const {
223     return mFd.getFD();
224 }
225 
getFlags()226 inline int MdpCtrl::getFlags() const {
227     return mOVInfo.flags;
228 }
229 
setFlags(int f)230 inline void MdpCtrl::setFlags(int f) {
231     mOVInfo.flags = f;
232 }
233 
setZ(overlay::utils::eZorder z)234 inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
235     mOVInfo.z_order = z;
236 }
237 
setIsFg(overlay::utils::eIsFg isFg)238 inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
239     mOVInfo.is_fg = isFg;
240 }
241 
setDownscale(int dscale)242 inline void MdpCtrl::setDownscale(int dscale) {
243     mDownscale = dscale;
244 }
245 
setPlaneAlpha(int planeAlpha)246 inline void MdpCtrl::setPlaneAlpha(int planeAlpha) {
247     mOVInfo.alpha = planeAlpha;
248 }
249 
setBlending(overlay::utils::eBlending blending)250 inline 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 
ovChanged()266 inline 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 
save()281 inline 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 
restore()289 inline 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 
getSrcWhf()297 inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
298     return utils::Whf(  mOVInfo.src.width,
299                         mOVInfo.src.height,
300                         mOVInfo.src.format);
301 }
302 
setSrcWhf(const overlay::utils::Whf & whf)303 inline 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 
getSrcRectDim()309 inline 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 
setSrcRectDim(const overlay::utils::Dim d)316 inline 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 
getDstRectDim()323 inline 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 
setDstRectDim(const overlay::utils::Dim d)330 inline 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 
getUserData()337 inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }
338 
setUserData(int v)339 inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }
340 
setRotationFlags()341 inline 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 
MdpCtrl3D()349 inline MdpCtrl3D::MdpCtrl3D() { reset(); }
close()350 inline 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 }
reset()361 inline void MdpCtrl3D::reset() {
362     utils::memset0(m3DOVInfo);
363 }
364 
setFd(int fd)365 inline void MdpCtrl3D::setFd(int fd) {
366     mFd.copy(fd);
367     OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid");
368 }
369 
setWh(const utils::Whf & whf)370 inline 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 
useVirtualFB()376 inline 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 
MdpData()389 inline MdpData::MdpData() { reset(); }
390 
~MdpData()391 inline MdpData::~MdpData() { close(); }
392 
init(uint32_t fbnum)393 inline 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 
reset()402 inline void MdpData::reset() {
403     overlay::utils::memset0(mOvData);
404     mOvData.data.memory_id = -1;
405 }
406 
close()407 inline bool MdpData::close() {
408     reset();
409     return mFd.close();
410 }
411 
getSrcMemoryId()412 inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }
413 
setPipeId(int id)414 inline void MdpData::setPipeId(int id) { mOvData.id = id; }
415 
getPipeId()416 inline int MdpData::getPipeId() const { return mOvData.id; }
417 
getFd()418 inline int MdpData::getFd() const { return mFd.getFD(); }
419 
play(int fd,uint32_t offset)420 inline 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