blob: 39c4f0c1d34f7f990e22a5be4b752b303546619c [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
2* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above
10* copyright notice, this list of conditions and the following
11* disclaimer in the documentation and/or other materials provided
12* with the distribution.
13* * Neither the name of Code Aurora Forum, Inc. nor the names of its
14* contributors may be used to endorse or promote products derived
15* from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#ifndef OVERLAY_ROTATOR_H
31#define OVERLAY_ROTATOR_H
32
33#include <stdlib.h>
34
35#include "mdpWrapper.h"
36#include "overlayUtils.h"
37#include "overlayMem.h"
38
39namespace overlay {
40 class MdpCtrl;
41/*
42* MDP rot holds MDP's rotation related structures.
43*
44* */
45class MdpRot {
46public:
47 /* ctor */
48 explicit MdpRot();
49
50 /* open fd for rotator. map bufs is defered */
51 bool open();
52
53 /* remap rot buffers */
54 bool remap(uint32_t numbufs, const utils::PipeArgs& args);
55
56 /* Unmap everything that is not current */
57 bool unmapNonCurrent();
58
59 /* close fd, mem */
60 bool close();
61
62 /* reset underlying data, basically memset 0 */
63 void reset();
64
65 /* calls underlying wrappers to start rotator */
66 bool start();
67
68 /* start underlying but use given whf and flags */
69 bool start(const utils::PipeArgs& args);
70
71 /* start underlying but use given whf and flags.
72 * Has the ability to parameterize the dst fmt */
73 template <int ROT_OUT_FMT>
74 bool start(const utils::PipeArgs& args);
75
76 /* assign memory id to mdp structure */
77 void setDataMemId(int fd);
78 void setRotDataSrcMemId(int fd);
79
80 /* Mark src as FB (non-ION) */
81 void setSrcFB(bool);
82
83 /* get dst (for offset and memory id) non-virt */
84 int getDstMemId() const;
85 uint32_t getDstOffset() const;
86
87 /* set enable/disable flag */
88 void setEnable();
89 void setDisable();
90 bool enabled() const;
91
92 /* set rotator flag*/
93 void setRotations(uint32_t r);
94
95 /* set the req data id in mData */
96 void setDataReqId(int id);
97
98 /* swap rot info dst w/h */
99 void swapDstWH();
100
101 /* returns a copy of src whf */
102 utils::Whf getSrcWhf() const;
103
104 /* setup rotator data before queue buf calls
105 * call play if rotate call succeed. return false if failed */
106 bool prepareQueueBuf(uint32_t offset);
107
108 /* call play on mdp*/
109 bool play(int fd);
110
111 /* set src whf */
112 void setSrcWhf(const utils::Whf& whf);
113
114 /* returns rotator session id */
115 int getSessId() const;
116
117 /* dump the state of the object */
118 void dump() const;
119
120private:
121 bool open_i(uint32_t numbufs, uint32_t bufsz);
122
123 /* max buf no for offset */
124 enum { ROT_MAX_BUF_OFFSET = 2 };
125 /* rot info*/
126 msm_rotator_img_info mRotImgInfo;
127 /* rot data */
128 msm_rotator_data_info mRotDataInfo;
129 /* data needed for rotator */
130 msmfb_overlay_data mData;
131 /* rotator fd */
132 OvFD mFd;
133 /* Array of memory map for rotator
134 * The array enable us to change rot buffers/mapping
135 * on the fly*/
136 struct RotMem {
137 enum {MAX_ROT_MEM = 2};
138 struct Mem {
139 Mem() : mCurrOffset(0) {utils::memset0(mRotOffset); }
140 bool valid() { return m.valid(); }
141 bool close() { return m.close(); }
142 uint32_t size() const { return m.bufSz(); }
143 /* rotator data info dst offset */
144 uint32_t mRotOffset[ROT_MAX_BUF_OFFSET];
145 /* current offset slot from mRotOffset */
146 uint32_t mCurrOffset;
147 OvMem m;
148 };
149 RotMem() : _curr(0) {}
150 Mem& curr() { return m[_curr % MAX_ROT_MEM]; }
151 const Mem& curr() const { return m[_curr % MAX_ROT_MEM]; }
152 Mem& prev() { return m[(_curr+1) % MAX_ROT_MEM]; }
153 RotMem& operator++() { ++_curr; return *this; }
154 bool close();
155 uint32_t _curr;
156 Mem m[MAX_ROT_MEM];
157 } mMem;
158 bool isSrcFB;
159};
160
161/*
162* RotatorBase. No memebers, just interface.
163* ~ can also be =0 with empty impl in cpp.
164* */
165class RotatorBase {
166public:
167 /* Most of the below are No op funcs for RotatorBase */
168 virtual ~RotatorBase() {}
169 virtual bool open() = 0;
170 virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args) = 0;
171 virtual bool close() = 0;
172 virtual bool start(const utils::PipeArgs& args) = 0;
173 virtual bool start() = 0;
174 virtual mdp_overlay setInfo(const utils::PipeArgs& args,
175 const mdp_overlay& o) = 0;
176 virtual bool overlayTransform(MdpCtrl& mdp,
177 utils::eTransform& rot) = 0;
178 virtual void setSrcWhf(const utils::Whf& wfh) = 0;
179 virtual utils::Whf getSrcWhf() const = 0;
180 virtual void setRotations(uint32_t r) = 0;
181 virtual void setDataReqId(int id) = 0;
182 virtual bool prepareQueueBuf(uint32_t offset) = 0;
183 virtual bool play(int fd) = 0;
184 virtual void setEnable() = 0;
185 virtual void setDisable() = 0;
186 virtual bool enabled() const = 0;
187 virtual void setDataMemId(int fd) = 0;
188 virtual void setRotDataSrcMemId(int fd) = 0;
189 virtual void setSrcFB(bool) = 0;
190 virtual int getSessId() const = 0;
191 virtual void dump() const = 0;
192};
193
194/*
195* Null/Empty impl of RotatorBase
196* */
197class NullRotator : public RotatorBase {
198public:
199 /* Most of the below are No op funcs for RotatorBase */
200 virtual ~NullRotator();
201 virtual bool open();
202 virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args);
203 virtual bool close();
204 virtual bool start(const utils::PipeArgs& args);
205 virtual bool start();
206 /* null rotator behavior should set info in a specific way */
207 virtual mdp_overlay setInfo(const utils::PipeArgs& args,
208 const mdp_overlay& o);
209 virtual bool overlayTransform(MdpCtrl& o,
210 utils::eTransform& rot);
211 virtual void setSrcWhf(const utils::Whf& wfh);
212 virtual utils::Whf getSrcWhf() const;
213 virtual void setRotations(uint32_t r);
214 virtual void setDataReqId(int id);
215 virtual bool prepareQueueBuf(uint32_t offset);
216 virtual bool play(int fd);
217 virtual void setEnable();
218 virtual void setDisable();
219 virtual bool enabled () const;
220 virtual void setDataMemId(int fd);
221 virtual void setRotDataSrcMemId(int fd);
222 virtual void setSrcFB(bool);
223 virtual int getSessId() const;
224 virtual void dump() const;
225};
226
227
228/*
229* Rotator impl.
230* */
231class Rotator : public RotatorBase
232{
233public:
234 /* construct underlying object */
235 explicit Rotator();
236
237 /* close underlying rot */
238 virtual ~Rotator();
239
240 /* calls underlying open */
241 virtual bool open();
242
243 /* remap rot buffers */
244 virtual bool remap(uint32_t numbufs, const utils::PipeArgs& args);
245
246 /* calls underlying close */
247 virtual bool close();
248
249 /* calls underlying start */
250 virtual bool start();
251
252 /* calls underlying start with whf and flags */
253 virtual bool start(const utils::PipeArgs& args);
254
255 /* non virtual - calls underlying start with whf and flags.
256 * Has the ability to parameterize the dst */
257 template <int ROT_OUT_FMT>
258 bool start(const utils::PipeArgs& args);
259
260 /* Unmap everything that is not current */
261 bool unmapNonCurrent();
262
263 /* set info using whf and given mdp */
264 virtual mdp_overlay setInfo(const utils::PipeArgs& args,
265 const mdp_overlay& o);
266
267 /* transform function for the MDP */
268 virtual bool overlayTransform(MdpCtrl& mdp,
269 utils::eTransform& rot);
270
271 /* set src whf */
272 virtual void setSrcWhf(const utils::Whf& wfh);
273
274 /* set Rotations */
275 virtual void setRotations(uint32_t r);
276
277 /* set the req data id in mData */
278 virtual void setDataReqId(int id);
279
280 /* set memory_id */
281 virtual void setDataMemId(int fd);
282 virtual void setRotDataSrcMemId(int fd);
283
284 /* Mark the src for rotator as FB. usually set by UI mirroing cases */
285 virtual void setSrcFB(bool);
286
287 /* get dst (for offset and memory id) non-virt */
288 int getDstMemId() const;
289 uint32_t getDstOffset() const;
290
291 /* set enable/disable flag */
292 virtual void setEnable();
293 virtual void setDisable();
294 virtual bool enabled () const;
295
296 /* return rotator sess id */
297 virtual int getSessId() const;
298
299 /* return a copy of src whf*/
300 virtual utils::Whf getSrcWhf() const;
301
302 /* prepare rot for queue buf*/
303 virtual bool prepareQueueBuf(uint32_t offset);
304
305 /* call play on mdp*/
306 virtual bool play(int fd);
307
308 /* dump the state of the object */
309 virtual void dump() const;
310private:
311 /* helper functions for overlayTransform */
312 void overlayTransFlipHV(MdpCtrl& mdp,
313 utils::eTransform& rot);
314 void overlayTransFlipRot90(MdpCtrl& mdp,
315 utils::eTransform& rot);
316 void overlayTransFlipRot180(MdpCtrl& mdp);
317 void overlayTransFlipRot270(MdpCtrl& mdp);
318
319 /* underlying rotator MDP object */
320 MdpRot mRot;
321};
322
323
324//--------------inlines------------------------------------
325//// MdpRot ////
326inline MdpRot::MdpRot() { reset(); }
327inline bool MdpRot::start(const utils::PipeArgs& args) {
328 return this->start<utils::ROT_OUT_FMT_DEFAULT>(args);
329}
330
331inline void MdpRot::setDataMemId(int fd) { mData.data.memory_id = fd; }
332inline void MdpRot::setRotDataSrcMemId(int fd) {
333 mRotDataInfo.src.memory_id = fd; }
334
335inline void MdpRot::setEnable() { mRotImgInfo.enable = 1; }
336inline void MdpRot::setDisable() { mRotImgInfo.enable = 0; }
337inline bool MdpRot::enabled() const { return mRotImgInfo.enable; }
338
339inline void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = r; }
340inline void MdpRot::setDataReqId(int id) { mData.id = id; }
341inline void MdpRot::swapDstWH() {
342 overlay::utils::swap(mRotImgInfo.dst.width,
343 mRotImgInfo.dst.height); }
344
345inline overlay::utils::Whf MdpRot::getSrcWhf() const {
346 return overlay::utils::Whf(mRotImgInfo.src.width,
347 mRotImgInfo.src.height,
348 mRotImgInfo.src.format);
349}
350
351inline int MdpRot::getDstMemId() const {
352 return mRotDataInfo.dst.memory_id;
353}
354inline uint32_t MdpRot::getDstOffset() const {
355 return mRotDataInfo.dst.offset;
356}
357
358inline void MdpRot::setSrcWhf(const overlay::utils::Whf& whf) {
359 mRotImgInfo.src.width = whf.w;
360 mRotImgInfo.src.height = whf.h;
361 mRotImgInfo.src.format = whf.format;
362}
363
364inline int MdpRot::getSessId() const { return mRotImgInfo.session_id; }
365
366inline void MdpRot::setSrcFB(bool mark) { isSrcFB = mark; }
367
368///// Null Rotator /////
369inline NullRotator::~NullRotator() {}
370inline bool NullRotator::open() {
371 return true; }
372inline bool NullRotator::remap(uint32_t numbufs,
373 const utils::PipeArgs& args){
374 return true; }
375inline bool NullRotator::close() { return true; }
376inline bool NullRotator::start(const utils::PipeArgs& args)
377{ return true; }
378
379inline bool NullRotator::start() { return true; }
380inline bool NullRotator::overlayTransform(MdpCtrl& o,
381 utils::eTransform& rot)
382{ return true; }
383inline void NullRotator::setSrcWhf(const overlay::utils::Whf& wfh) {}
384inline void NullRotator::setRotations(uint32_t) {}
385inline void NullRotator::setDataReqId(int id) {}
386inline void NullRotator::setEnable() {}
387inline void NullRotator::setDisable() {}
388inline bool NullRotator::enabled() const { return false; }
389inline int NullRotator::getSessId() const { return -1; }
390inline overlay::utils::Whf NullRotator::getSrcWhf() const {
391 return overlay::utils::Whf(); }
392inline bool NullRotator::prepareQueueBuf(uint32_t offset)
393{ return true; }
394inline bool NullRotator::play(int fd)
395{ return true; }
396inline void NullRotator::setDataMemId(int fd) {}
397inline void NullRotator::setRotDataSrcMemId(int fd) {}
398inline void NullRotator::setSrcFB(bool) {}
399inline void NullRotator::dump() const {
400 ALOGE("== Dump NullRotator dump (null) start/end ==");
401}
402
403///// Rotator /////
404inline Rotator::Rotator() { }
405
406inline Rotator::~Rotator() {
407 mRot.close(); // also will do reset
408}
409
410inline bool Rotator::open() {
411 if(!mRot.open()) {
412 ALOGE("Rotator::open failed");
413 return false;
414 }
415 return true;
416}
417
418template <int ROT_OUT_FMT>
419inline bool Rotator::start(const utils::PipeArgs& args) {
420 return mRot.start<ROT_OUT_FMT>(args);
421}
422
423inline bool Rotator::remap(uint32_t numbufs,
424 const utils::PipeArgs& args){
425 if(!mRot.remap(numbufs, args)) {
426 ALOGE("%s failed", __FUNCTION__);
427 return false;
428 }
429 return true;
430}
431
432inline bool Rotator::close() {
433 return mRot.close();
434}
435
436inline bool Rotator::start() {
437 return mRot.start();
438}
439
440inline bool Rotator::start(const utils::PipeArgs& args) {
441 return mRot.start(args);
442}
443
444inline bool Rotator::unmapNonCurrent() {
445 return mRot.unmapNonCurrent();
446}
447
448inline void Rotator::setEnable(){ mRot.setEnable(); }
449inline void Rotator::setDisable(){ mRot.setDisable(); }
450inline bool Rotator::enabled() const { return mRot.enabled(); }
451inline void Rotator::setDataMemId(int fd) {
452 mRot.setDataMemId(fd); }
453
454inline void Rotator::setRotDataSrcMemId(int fd) {
455 mRot.setRotDataSrcMemId(fd);
456}
457
458inline void Rotator::setSrcFB(bool mark) { mRot.setSrcFB(mark); }
459
460inline int Rotator::getDstMemId() const {
461 return mRot.getDstMemId();
462}
463inline uint32_t Rotator::getDstOffset() const {
464 return mRot.getDstOffset();
465}
466
467inline void Rotator::setDataReqId(int id) {
468 mRot.setDataReqId(id);
469}
470
471inline void Rotator::setSrcWhf(
472 const overlay::utils::Whf& whf) {
473 mRot.setSrcWhf(whf);
474}
475
476inline void Rotator::setRotations(uint32_t rot) {
477 mRot.setRotations (rot);
478}
479
480inline int Rotator::getSessId() const {
481 return mRot.getSessId(); }
482
483inline void Rotator::dump() const {
484 ALOGE("== Dump Rotator start ==");
485 mRot.dump();
486 ALOGE("== Dump Rotator end ==");
487}
488
489inline overlay::utils::Whf Rotator::getSrcWhf() const {
490 return mRot.getSrcWhf(); }
491
492inline bool Rotator::prepareQueueBuf(uint32_t offset)
493{
494 return mRot.prepareQueueBuf(offset);
495}
496
497inline bool Rotator::play(int fd)
498{
499 return mRot.play(fd);
500}
501
502template <int ROT_OUT_FMT>
503bool MdpRot::start(const utils::PipeArgs& args) {
504 // Do nothing when no orientation
505 if(utils::OVERLAY_TRANSFORM_0 == args.orientation &&
506 utils::ROT_FLAG_ENABLED != args.rotFlags) {
507 return true;
508 }
509 utils::Whf whf(args.whf);
510 mRotImgInfo.src.format = whf.format;
511 mRotImgInfo.src.width = whf.w;
512 mRotImgInfo.src.height = whf.h;
513 mRotImgInfo.src_rect.w = whf.w;
514 mRotImgInfo.src_rect.h = whf.h;
515 mRotImgInfo.dst.width = whf.w;
516 mRotImgInfo.dst.height = whf.h;
517 if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
518 whf.format == MDP_Y_CBCR_H2V2_TILE) {
519 mRotImgInfo.src.width = utils::alignup(whf.w, 64);
520 mRotImgInfo.src.height = utils::alignup(whf.h, 32);
521 mRotImgInfo.src_rect.w = utils::alignup(whf.w, 64);
522 mRotImgInfo.src_rect.h = utils::alignup(whf.h, 32);
523 mRotImgInfo.dst.width = utils::alignup(whf.w, 64);
524 mRotImgInfo.dst.height = utils::alignup(whf.h, 32);
525 mRotImgInfo.dst.format = MDP_Y_CRCB_H2V2;
526 }
527 // either utils::getRotOutFmt(whf.format); or supplied fmt
528 // utils::RotOutFmt<ROT_OUT_FMT_DEFAULT>::fmt;
529 mRotImgInfo.dst.format = utils::RotOutFmt<ROT_OUT_FMT>::fmt(whf.format);
530 mRotImgInfo.dst_x = 0;
531 mRotImgInfo.dst_y = 0;
532 mRotImgInfo.src_rect.x = 0;
533 mRotImgInfo.src_rect.y = 0;
534 mRotImgInfo.rotations = 0;
535 // ROT_FLAG_DISABLED / ENABLED
536 // Refer to overlayUtils.h eRotFlags
537 // for more info
538 mRotImgInfo.enable = args.rotFlags;
539 mRotImgInfo.session_id = mRotImgInfo.session_id ?
540 mRotImgInfo.session_id : 0;
541
542 return start();
543}
544
545} // overlay
546
547namespace {
548// just a helper func for Rotator common operations x-(y+z)
549int compute(uint32_t x, uint32_t y, uint32_t z) {
550 return x-(y+z);
551}
552}
553
554#endif // OVERLAY_ROTATOR_H