1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright (c) 2010-2012, Code Aurora Forum. 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
26 namespace overlay{
27
28 /*
29 * Mdp Ctrl holds corresponding fd and MDP related struct.
30 * It is simple wrapper to MDP services
31 * */
32 class MdpCtrl {
33 public:
34 /* ctor reset */
35 explicit MdpCtrl();
36
37 /* dtor close */
38 ~MdpCtrl();
39
40 /* init underlying device using fbnum */
41 bool init(uint32_t fbnum);
42
43 /* unset overlay, reset and close fd */
44 bool close();
45
46 /* reset and set ov id to -1 / MSMFB_NEW_REQUEST */
47 void reset();
48
49 /* get orient / user_data[0] */
50 int getOrient() const;
51
52 /* returns session id */
53 int getPipeId() const;
54
55 /* returns the fd associated to ctrl*/
56 int getFd() const;
57
58 /* Get screen info. out: info*/
59 bool getScreenInfo(utils::ScreenInfo& info);
60
61 /* overlay get */
62 bool get();
63
64 /* returns flags from mdp structure */
65 int getFlags() const;
66
67 /* set flags to mdp structure */
68 void setFlags(int f);
69
70 /* set z order */
71 void setZ(utils::eZorder z);
72
73 /* set isFg flag */
74 void setIsFg(utils::eIsFg isFg);
75
76 /* calls overlay set
77 * Set would always consult last good known ov instance.
78 * Only if it is different, set would actually exectue ioctl.
79 * On a sucess ioctl. last good known ov instance is updated */
80 bool set();
81
82 /* return a copy of src whf*/
83 utils::Whf getSrcWhf() const;
84
85 /* set src whf */
86 void setSrcWhf(const utils::Whf& whf);
87
88 /* adjust source width height format based on rot info */
89 void adjustSrcWhf(const bool& rotUsed);
90
91 /* swap src w/h*/
92 void swapSrcWH();
93
94 /* swap src rect w/h */
95 void swapSrcRectWH();
96
97 /* returns a copy to src rect dim */
98 utils::Dim getSrcRectDim() const;
99
100 /* set src/dst rect dim */
101 void setSrcRectDim(const utils::Dim d);
102 void setDstRectDim(const utils::Dim d);
103
104 /* returns a copy ro dst rect dim */
105 utils::Dim getDstRectDim() const;
106
107 /* returns user_data[0]*/
108 int getUserData() const;
109
110 /* sets user_data[0] */
111 void setUserData(int v);
112
113 /* return true if current overlay is different
114 * than last known good overlay */
115 bool ovChanged() const;
116
117 /* save mOVInfo to be last known good ov*/
118 void save();
119
120 /* restore last known good ov to be the current */
121 void restore();
122
123 /* Sets the source total width, height, format */
124 bool setSource(const utils::PipeArgs& pargs);
125
126 /*
127 * Sets ROI, the unpadded region, for source buffer.
128 * Should be called before a setPosition, for small clips.
129 * Dim - ROI dimensions.
130 */
131 bool setCrop(const utils::Dim& d);
132
133 bool setTransform(const utils::eTransform& orient, const bool& rotUsed);
134
135 /* given a dim and w/h, set overlay dim */
136 bool setPosition(const utils::Dim& dim, int w, int h);
137
138 /* using user_data, sets/unsets roationvalue in mdp flags */
139 void setRotationFlags();
140
141 /* dump state of the object */
142 void dump() const;
143
144 private:
145
146 /* helper functions for overlayTransform */
147 void doTransform();
148 void overlayTransFlipH();
149 void overlayTransFlipV();
150 void overlayTransRot90();
151
152 utils::eTransform mOrientation; //Holds requested orientation
153 bool mRotUsed; //whether rotator should be used even if requested
154 //orientation is 0.
155
156 /* last good known ov info */
157 mdp_overlay mLkgo;
158
159 /* Actual overlay mdp structure */
160 mdp_overlay mOVInfo;
161
162 /* FD for the mdp fbnum */
163 OvFD mFd;
164 };
165
166
167 /* MDP 3D related ctrl */
168 class MdpCtrl3D {
169 public:
170 /* ctor reset data */
171 MdpCtrl3D();
172 /* calls MSMFB_OVERLAY_3D */
173 bool close();
174 /* set w/h. format is ignored*/
175 void setWh(const utils::Whf& whf);
176 /* set is_3d calls MSMFB_OVERLAY_3D */
177 bool useVirtualFB();
178 /* set fd to be used in ioctl */
179 void setFd(int fd);
180 /* dump */
181 void dump() const;
182 private:
183 /* reset */
184 void reset();
185 /* actual MSM 3D info */
186 msmfb_overlay_3d m3DOVInfo;
187 /* FD for the mdp 3D */
188 OvFD mFd;
189 };
190
191 /* MDP data */
192 class MdpData {
193 public:
194 /* ctor reset data */
195 explicit MdpData();
196
197 /* dtor close*/
198 ~MdpData();
199
200 /* init FD */
201 bool init(uint32_t fbnum);
202
203 /* memset0 the underlying mdp object */
204 void reset();
205
206 /* close fd, and reset */
207 bool close();
208
209 /* set id of mdp data */
210 void setPipeId(int id);
211
212 /* return ses id of data */
213 int getPipeId() const;
214
215 /* get underlying fd*/
216 int getFd() const;
217
218 /* get memory_id */
219 int getSrcMemoryId() const;
220
221 /* calls wrapper play */
222 bool play(int fd, uint32_t offset);
223
224 /* dump state of the object */
225 void dump() const;
226 private:
227
228 /* actual overlay mdp data */
229 msmfb_overlay_data mOvData;
230
231 /* fd to mdp fbnum */
232 OvFD mFd;
233 };
234
235 //--------------Inlines---------------------------------
236 namespace {
237 // just a helper func for common operations x-(y+z)
compute(uint32_t x,uint32_t y,uint32_t z)238 int compute(uint32_t x, uint32_t y, uint32_t z) {
239 return x-(y+z);
240 }
241 }
242
243 ///// MdpCtrl //////
244
MdpCtrl()245 inline MdpCtrl::MdpCtrl() {
246 reset();
247 }
248
~MdpCtrl()249 inline MdpCtrl::~MdpCtrl() {
250 close();
251 }
252
getOrient()253 inline int MdpCtrl::getOrient() const {
254 return getUserData();
255 }
256
getPipeId()257 inline int MdpCtrl::getPipeId() const {
258 return mOVInfo.id;
259 }
260
getFd()261 inline int MdpCtrl::getFd() const {
262 return mFd.getFD();
263 }
264
getFlags()265 inline int MdpCtrl::getFlags() const {
266 return mOVInfo.flags;
267 }
268
setFlags(int f)269 inline void MdpCtrl::setFlags(int f) {
270 mOVInfo.flags = f;
271 }
272
setZ(overlay::utils::eZorder z)273 inline void MdpCtrl::setZ(overlay::utils::eZorder z) {
274 mOVInfo.z_order = z;
275 }
276
setIsFg(overlay::utils::eIsFg isFg)277 inline void MdpCtrl::setIsFg(overlay::utils::eIsFg isFg) {
278 mOVInfo.is_fg = isFg;
279 }
280
ovChanged()281 inline bool MdpCtrl::ovChanged() const {
282 // 0 means same
283 if(0 == ::memcmp(&mOVInfo, &mLkgo, sizeof (mdp_overlay))) {
284 return false;
285 }
286 return true;
287 }
288
save()289 inline void MdpCtrl::save() {
290 if(static_cast<ssize_t>(mOVInfo.id) == MSMFB_NEW_REQUEST) {
291 ALOGE("MdpCtrl current ov has id -1, will not save");
292 return;
293 }
294 mLkgo = mOVInfo;
295 }
296
restore()297 inline void MdpCtrl::restore() {
298 if(static_cast<ssize_t>(mLkgo.id) == MSMFB_NEW_REQUEST) {
299 ALOGE("MdpCtrl Lkgo ov has id -1, will not restore");
300 return;
301 }
302 mOVInfo = mLkgo;
303 }
304
getSrcWhf()305 inline overlay::utils::Whf MdpCtrl::getSrcWhf() const {
306 return utils::Whf( mOVInfo.src.width,
307 mOVInfo.src.height,
308 mOVInfo.src.format);
309 }
310
setSrcWhf(const overlay::utils::Whf & whf)311 inline void MdpCtrl::setSrcWhf(const overlay::utils::Whf& whf) {
312 mOVInfo.src.width = whf.w;
313 mOVInfo.src.height = whf.h;
314 mOVInfo.src.format = whf.format;
315 }
316
getSrcRectDim()317 inline overlay::utils::Dim MdpCtrl::getSrcRectDim() const {
318 return utils::Dim( mOVInfo.src_rect.x,
319 mOVInfo.src_rect.y,
320 mOVInfo.src_rect.w,
321 mOVInfo.src_rect.h);
322 }
323
setSrcRectDim(const overlay::utils::Dim d)324 inline void MdpCtrl::setSrcRectDim(const overlay::utils::Dim d) {
325 mOVInfo.src_rect.x = d.x;
326 mOVInfo.src_rect.y = d.y;
327 mOVInfo.src_rect.w = d.w;
328 mOVInfo.src_rect.h = d.h;
329 }
330
getDstRectDim()331 inline overlay::utils::Dim MdpCtrl::getDstRectDim() const {
332 return utils::Dim( mOVInfo.dst_rect.x,
333 mOVInfo.dst_rect.y,
334 mOVInfo.dst_rect.w,
335 mOVInfo.dst_rect.h);
336 }
337
setDstRectDim(const overlay::utils::Dim d)338 inline void MdpCtrl::setDstRectDim(const overlay::utils::Dim d) {
339 mOVInfo.dst_rect.x = d.x;
340 mOVInfo.dst_rect.y = d.y;
341 mOVInfo.dst_rect.w = d.w;
342 mOVInfo.dst_rect.h = d.h;
343 }
344
getUserData()345 inline int MdpCtrl::getUserData() const { return mOVInfo.user_data[0]; }
346
setUserData(int v)347 inline void MdpCtrl::setUserData(int v) { mOVInfo.user_data[0] = v; }
348
setRotationFlags()349 inline void MdpCtrl::setRotationFlags() {
350 const int u = getUserData();
351 if (u == MDP_ROT_90 || u == MDP_ROT_270)
352 mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
353 else
354 mOVInfo.flags &= ~MDP_SOURCE_ROTATED_90;
355 }
356
swapSrcWH()357 inline void MdpCtrl::swapSrcWH() {
358 utils::swap(mOVInfo.src.width,
359 mOVInfo.src.height);
360 }
361
swapSrcRectWH()362 inline void MdpCtrl::swapSrcRectWH() {
363 utils::swap(mOVInfo.src_rect.w,
364 mOVInfo.src_rect.h);
365 }
366
overlayTransFlipH()367 inline void MdpCtrl::overlayTransFlipH()
368 {
369 utils::Dim d = getSrcRectDim();
370 utils::Whf whf = getSrcWhf();
371 d.x = compute(whf.w, d.x, d.w);
372 setSrcRectDim(d);
373 }
374
overlayTransFlipV()375 inline void MdpCtrl::overlayTransFlipV()
376 {
377 utils::Dim d = getSrcRectDim();
378 utils::Whf whf = getSrcWhf();
379 d.y = compute(whf.h, d.y, d.h);
380 setSrcRectDim(d);
381 }
382
overlayTransRot90()383 inline void MdpCtrl::overlayTransRot90()
384 {
385 utils::Dim d = getSrcRectDim();
386 utils::Whf whf = getSrcWhf();
387 int tmp = d.x;
388 d.x = compute(whf.h,
389 d.y,
390 d.h);
391 d.y = tmp;
392 setSrcRectDim(d);
393 swapSrcWH();
394 swapSrcRectWH();
395 }
396
397
398 /////// MdpCtrl3D //////
399
MdpCtrl3D()400 inline MdpCtrl3D::MdpCtrl3D() { reset(); }
close()401 inline bool MdpCtrl3D::close() {
402 if (m3DOVInfo.is_3d) {
403 m3DOVInfo.is_3d = 0;
404 if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
405 ALOGE("MdpCtrl3D close failed set3D with 0");
406 return false;
407 }
408 }
409 reset();
410 return true;
411 }
reset()412 inline void MdpCtrl3D::reset() {
413 utils::memset0(m3DOVInfo);
414 }
415
setFd(int fd)416 inline void MdpCtrl3D::setFd(int fd) {
417 mFd.copy(fd);
418 OVASSERT(mFd.valid(), "MdpCtrl3D setFd, FD should be valid");
419 }
420
setWh(const utils::Whf & whf)421 inline void MdpCtrl3D::setWh(const utils::Whf& whf) {
422 // ignore fmt. Needed for useVirtualFB callflow
423 m3DOVInfo.width = whf.w;
424 m3DOVInfo.height = whf.h;
425 }
426
useVirtualFB()427 inline bool MdpCtrl3D::useVirtualFB() {
428 if(!m3DOVInfo.is_3d) {
429 m3DOVInfo.is_3d = 1;
430 if(!mdp_wrapper::set3D(mFd.getFD(), m3DOVInfo)) {
431 ALOGE("MdpCtrl3D close failed set3D with 0");
432 return false;
433 }
434 }
435 return true;
436 }
437
438 /////// MdpData //////
439
MdpData()440 inline MdpData::MdpData() { reset(); }
441
~MdpData()442 inline MdpData::~MdpData() { close(); }
443
init(uint32_t fbnum)444 inline bool MdpData::init(uint32_t fbnum) {
445 // FD init
446 if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
447 ALOGE("Ctrl failed to init fbnum=%d", fbnum);
448 return false;
449 }
450 return true;
451 }
452
reset()453 inline void MdpData::reset() {
454 overlay::utils::memset0(mOvData);
455 mOvData.data.memory_id = -1;
456 }
457
close()458 inline bool MdpData::close() {
459 reset();
460 return mFd.close();
461 }
462
getSrcMemoryId()463 inline int MdpData::getSrcMemoryId() const { return mOvData.data.memory_id; }
464
setPipeId(int id)465 inline void MdpData::setPipeId(int id) { mOvData.id = id; }
466
getPipeId()467 inline int MdpData::getPipeId() const { return mOvData.id; }
468
getFd()469 inline int MdpData::getFd() const { return mFd.getFD(); }
470
play(int fd,uint32_t offset)471 inline bool MdpData::play(int fd, uint32_t offset) {
472 mOvData.data.memory_id = fd;
473 mOvData.data.offset = offset;
474 if(!mdp_wrapper::play(mFd.getFD(), mOvData)){
475 ALOGE("MdpData failed to play");
476 dump();
477 return false;
478 }
479 return true;
480 }
481
482 } // overlay
483
484 #endif // OVERLAY_MDP_H
485