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