1 /*
2 * Copyright (c) 2011-2013, The Linux Foundation. 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 The Linux Foundation 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_UTILS_H
31 #define OVERLAY_UTILS_H
32 
33 #include <cutils/log.h> // ALOGE, etc
34 #include <errno.h>
35 #include <fcntl.h> // open, O_RDWR, etc
36 #include <hardware/hardware.h>
37 #include <hardware/gralloc.h> // buffer_handle_t
38 #include <linux/msm_mdp.h> // flags
39 #include <linux/msm_rotator.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/stat.h>
44 #include <sys/types.h>
45 #include <utils/Log.h>
46 #include "gralloc_priv.h" //for interlace
47 
48 // Older platforms do not support Venus.
49 #ifndef VENUS_COLOR_FORMAT
50 #define MDP_Y_CBCR_H2V2_VENUS (MDP_IMGTYPE_LIMIT2 + 1)
51 #endif
52 
53 /*
54 *
55 * Collection of utilities functions/structs/enums etc...
56 *
57 * */
58 
59 // comment that out if you want to remove asserts
60 // or put it as -D in Android.mk. your choice.
61 #define OVERLAY_HAS_ASSERT
62 
63 #ifdef OVERLAY_HAS_ASSERT
64 # define OVASSERT(x, ...) if(!(x)) { ALOGE(__VA_ARGS__); abort(); }
65 #else
66 # define OVASSERT(x, ...) ALOGE_IF(!(x), __VA_ARGS__)
67 #endif // OVERLAY_HAS_ASSERT
68 
69 #define DEBUG_OVERLAY 0
70 #define PROFILE_OVERLAY 0
71 
72 #ifndef MDSS_MDP_RIGHT_MIXER
73 #define MDSS_MDP_RIGHT_MIXER 0x100
74 #endif
75 
76 #ifndef MDP_OV_PIPE_FORCE_DMA
77 #define MDP_OV_PIPE_FORCE_DMA 0x4000
78 #endif
79 
80 #define FB_DEVICE_TEMPLATE "/dev/graphics/fb%u"
81 #define NUM_FB_DEVICES 3
82 
83 namespace overlay {
84 
85 // fwd
86 class Overlay;
87 class OvFD;
88 
89 /* helper function to open by using fbnum */
90 bool open(OvFD& fd, uint32_t fbnum, const char* const dev,
91     int flags = O_RDWR);
92 
93 namespace utils {
94 struct Whf;
95 struct Dim;
96 
setBit(uint32_t x,uint32_t mask)97 inline uint32_t setBit(uint32_t x, uint32_t mask) {
98     return (x | mask);
99 }
100 
clrBit(uint32_t x,uint32_t mask)101 inline uint32_t clrBit(uint32_t x, uint32_t mask) {
102     return (x & ~mask);
103 }
104 
105 /* Utility class to help avoid copying instances by making the copy ctor
106 * and assignment operator private
107 *
108 * Usage:
109 *    class SomeClass : utils::NoCopy {...};
110 */
111 class NoCopy {
112 protected:
NoCopy()113     NoCopy(){}
~NoCopy()114     ~NoCopy() {}
115 private:
116     NoCopy(const NoCopy&);
117     const NoCopy& operator=(const NoCopy&);
118 };
119 
120 
121 /* 3D related utils, defines etc...
122  * The compound format passed to the overlay is
123  * ABCCC where A is the input 3D format
124  * B is the output 3D format
125  * CCC is the color format e.g YCbCr420SP YCrCb420SP etc */
126 enum { SHIFT_OUT_3D = 12,
127     SHIFT_TOT_3D = 16 };
128 enum { INPUT_3D_MASK = 0xFFFF0000,
129     OUTPUT_3D_MASK = 0x0000FFFF };
130 enum { BARRIER_LAND = 1,
131     BARRIER_PORT = 2 };
132 
format3D(uint32_t x)133 inline uint32_t format3D(uint32_t x) { return x & 0xFF000; }
format3DOutput(uint32_t x)134 inline uint32_t format3DOutput(uint32_t x) {
135     return (x & 0xF000) >> SHIFT_OUT_3D; }
format3DInput(uint32_t x)136 inline uint32_t format3DInput(uint32_t x) { return x & 0xF0000; }
137 
138 bool isHDMIConnected ();
139 bool is3DTV();
140 bool isPanel3D();
141 bool usePanel3D();
142 bool send3DInfoPacket (uint32_t fmt);
143 bool enableBarrier (uint32_t orientation);
144 uint32_t getS3DFormat(uint32_t fmt);
145 bool isMdssRotator();
146 
147 template <int CHAN>
148 bool getPositionS3D(const Whf& whf, Dim& out);
149 
150 template <int CHAN>
151 bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt);
152 
153 template <class Type>
154 void swapWidthHeight(Type& width, Type& height);
155 
156 struct Dim {
DimDim157     Dim () : x(0), y(0),
158     w(0), h(0),
159     o(0) {}
DimDim160     Dim(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h) :
161         x(_x), y(_y),
162         w(_w), h(_h) {}
DimDim163     Dim(uint32_t _x, uint32_t _y, uint32_t _w, uint32_t _h, uint32_t _o) :
164         x(_x), y(_y),
165         w(_w), h(_h),
166         o(_o) {}
checkDim167     bool check(uint32_t _w, uint32_t _h) const {
168         return (x+w <= _w && y+h <= _h);
169 
170     }
171 
172     bool operator==(const Dim& d) const {
173         return d.x == x && d.y == y &&
174                 d.w == w && d.h == h &&
175                 d.o == o;
176     }
177 
178     bool operator!=(const Dim& d) const {
179         return !operator==(d);
180     }
181 
182     void dump() const;
183     uint32_t x;
184     uint32_t y;
185     uint32_t w;
186     uint32_t h;
187     uint32_t o;
188 };
189 
190 // TODO have Whfz
191 
192 struct Whf {
WhfWhf193     Whf() : w(0), h(0), format(0), size(0) {}
WhfWhf194     Whf(uint32_t wi, uint32_t he, uint32_t f) :
195         w(wi), h(he), format(f), size(0) {}
WhfWhf196     Whf(uint32_t wi, uint32_t he, uint32_t f, uint32_t s) :
197         w(wi), h(he), format(f), size(s) {}
198     // FIXME not comparing size at the moment
199     bool operator==(const Whf& whf) const {
200         return whf.w == w && whf.h == h &&
201                 whf.format == format;
202     }
203     bool operator!=(const Whf& whf) const {
204         return !operator==(whf);
205     }
206     void dump() const;
207     uint32_t w;
208     uint32_t h;
209     uint32_t format;
210     uint32_t size;
211 };
212 
213 enum { MAX_PATH_LEN = 256 };
214 
215 enum { DEFAULT_PLANE_ALPHA = 0xFF };
216 
217 /**
218  * Rotator flags: not to be confused with orientation flags.
219  * Usually, you want to open the rotator to make sure it is
220  * ready for business.
221  * */
222  enum eRotFlags {
223     ROT_FLAGS_NONE = 0,
224     //Use rotator for 0 rotation. It is used anyway for others.
225     ROT_0_ENABLED = 1 << 0,
226     //Enable rotator downscale optimization for hardware bugs not handled in
227     //driver. If downscale optimizatation is required,
228     //then rotator will be used even if its 0 rotation case.
229     ROT_DOWNSCALE_ENABLED = 1 << 1,
230     ROT_PREROTATED = 1 << 2,
231 };
232 
233 enum eRotDownscale {
234     ROT_DS_NONE = 0,
235     ROT_DS_HALF = 1,
236     ROT_DS_FOURTH = 2,
237     ROT_DS_EIGHTH = 3,
238 };
239 
240 /* The values for is_fg flag for control alpha and transp
241  * IS_FG_OFF means is_fg = 0
242  * IS_FG_SET means is_fg = 1
243  */
244 enum eIsFg {
245     IS_FG_OFF = 0,
246     IS_FG_SET = 1
247 };
248 
249 /*
250  * Various mdp flags like PIPE SHARE, DEINTERLACE etc...
251  * kernel/common/linux/msm_mdp.h
252  * INTERLACE_MASK: hardware/qcom/display/libgralloc/badger/fb_priv.h
253  * */
254 enum eMdpFlags {
255     OV_MDP_FLAGS_NONE = 0,
256     OV_MDP_PIPE_SHARE =  MDP_OV_PIPE_SHARE,
257     OV_MDP_PIPE_FORCE_DMA = MDP_OV_PIPE_FORCE_DMA,
258     OV_MDP_DEINTERLACE = MDP_DEINTERLACE,
259     OV_MDP_SECURE_OVERLAY_SESSION = MDP_SECURE_OVERLAY_SESSION,
260     OV_MDP_SOURCE_ROTATED_90 = MDP_SOURCE_ROTATED_90,
261     OV_MDP_BACKEND_COMPOSITION = MDP_BACKEND_COMPOSITION,
262     OV_MDP_BLEND_FG_PREMULT = MDP_BLEND_FG_PREMULT,
263     OV_MDP_FLIP_H = MDP_FLIP_LR,
264     OV_MDP_FLIP_V = MDP_FLIP_UD,
265     OV_MDSS_MDP_RIGHT_MIXER = MDSS_MDP_RIGHT_MIXER,
266     OV_MDP_PP_EN = MDP_OVERLAY_PP_CFG_EN,
267 };
268 
269 enum eZorder {
270     ZORDER_0 = 0,
271     ZORDER_1,
272     ZORDER_2,
273     ZORDER_3,
274     Z_SYSTEM_ALLOC = 0xFFFF
275 };
276 
277 enum eMdpPipeType {
278     OV_MDP_PIPE_RGB = 0,
279     OV_MDP_PIPE_VG,
280     OV_MDP_PIPE_DMA,
281     OV_MDP_PIPE_ANY, //Any
282 };
283 
284 // Identify destination pipes
285 // TODO Names useless, replace with int and change all interfaces
286 enum eDest {
287     OV_P0 = 0,
288     OV_P1,
289     OV_P2,
290     OV_P3,
291     OV_P4,
292     OV_P5,
293     OV_P6,
294     OV_P7,
295     OV_P8,
296     OV_P9,
297     OV_INVALID,
298     OV_MAX = OV_INVALID,
299 };
300 
301 /* Used when a buffer is split over 2 pipes and sent to display */
302 enum {
303     OV_LEFT_SPLIT = 0,
304     OV_RIGHT_SPLIT,
305 };
306 
307 /* values for copybit_set_parameter(OVERLAY_TRANSFORM) */
308 enum eTransform {
309     /* No rot */
310     OVERLAY_TRANSFORM_0 = 0x0,
311     /* flip source image horizontally 0x1 */
312     OVERLAY_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H,
313     /* flip source image vertically 0x2 */
314     OVERLAY_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
315     /* rotate source image 180 degrees
316      * It is basically bit-or-ed  H | V == 0x3 */
317     OVERLAY_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
318     /* rotate source image 90 degrees 0x4 */
319     OVERLAY_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
320     /* rotate source image 90 degrees and flip horizontally 0x5 */
321     OVERLAY_TRANSFORM_ROT_90_FLIP_H = HAL_TRANSFORM_ROT_90 |
322                                       HAL_TRANSFORM_FLIP_H,
323     /* rotate source image 90 degrees and flip vertically 0x6 */
324     OVERLAY_TRANSFORM_ROT_90_FLIP_V = HAL_TRANSFORM_ROT_90 |
325                                       HAL_TRANSFORM_FLIP_V,
326     /* rotate source image 270 degrees
327      * Basically 180 | 90 == 0x7 */
328     OVERLAY_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
329     /* rotate invalid like in Transform.h */
330     OVERLAY_TRANSFORM_INV = 0x80
331 };
332 
333 enum eBlending {
334     OVERLAY_BLENDING_UNDEFINED = 0x0,
335     /* No blending */
336     OVERLAY_BLENDING_OPAQUE,
337     /* src.rgb + dst.rgb*(1-src_alpha) */
338     OVERLAY_BLENDING_PREMULT,
339     /* src.rgb * src_alpha + dst.rgb (1 - src_alpha) */
340     OVERLAY_BLENDING_COVERAGE,
341 };
342 
343 // Used to consolidate pipe params
344 struct PipeArgs {
PipeArgsPipeArgs345     PipeArgs() : mdpFlags(OV_MDP_FLAGS_NONE),
346         zorder(Z_SYSTEM_ALLOC),
347         isFg(IS_FG_OFF),
348         rotFlags(ROT_FLAGS_NONE),
349         planeAlpha(DEFAULT_PLANE_ALPHA),
350         blending(OVERLAY_BLENDING_COVERAGE){
351     }
352 
PipeArgsPipeArgs353     PipeArgs(eMdpFlags f, Whf _whf,
354             eZorder z, eIsFg fg, eRotFlags r,
355             int pA, eBlending b) :
356         mdpFlags(f),
357         whf(_whf),
358         zorder(z),
359         isFg(fg),
360         rotFlags(r),
361         planeAlpha(pA),
362         blending(b){
363     }
364 
365     eMdpFlags mdpFlags; // for mdp_overlay flags
366     Whf whf;
367     eZorder zorder; // stage number
368     eIsFg isFg; // control alpha & transp
369     eRotFlags rotFlags;
370     int planeAlpha;
371     eBlending blending;
372 };
373 
374 // Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time
375 // of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define
376 enum { HW_OV_MAGNIFICATION_LIMIT = 20,
377     HW_OV_MINIFICATION_LIMIT  = 8
378 };
379 
setMdpFlags(eMdpFlags & f,eMdpFlags v)380 inline void setMdpFlags(eMdpFlags& f, eMdpFlags v) {
381     f = static_cast<eMdpFlags>(setBit(f, v));
382 }
383 
clearMdpFlags(eMdpFlags & f,eMdpFlags v)384 inline void clearMdpFlags(eMdpFlags& f, eMdpFlags v) {
385     f = static_cast<eMdpFlags>(clrBit(f, v));
386 }
387 
388 // fb 0/1/2
389 enum { FB0, FB1, FB2 };
390 
391 //Panels could be categorized as primary and external
392 enum { PRIMARY, EXTERNAL };
393 
394 // 2 for rgb0/1 double bufs
395 enum { RGB_PIPE_NUM_BUFS = 2 };
396 
397 struct ScreenInfo {
ScreenInfoScreenInfo398     ScreenInfo() : mFBWidth(0),
399     mFBHeight(0),
400     mFBbpp(0),
401     mFBystride(0) {}
402     void dump(const char* const s) const;
403     uint32_t mFBWidth;
404     uint32_t mFBHeight;
405     uint32_t mFBbpp;
406     uint32_t mFBystride;
407 };
408 
409 int getMdpFormat(int format);
410 int getHALFormat(int mdpFormat);
411 int getDownscaleFactor(const int& src_w, const int& src_h,
412         const int& dst_w, const int& dst_h);
413 
414 /* flip is upside down and such. V, H flip
415  * rotation is 90, 180 etc
416  * It returns MDP related enum/define that match rot+flip*/
417 int getMdpOrient(eTransform rotation);
418 const char* getFormatString(int format);
419 
420 template <class T>
memset0(T & t)421 inline void memset0(T& t) { ::memset(&t, 0, sizeof(T)); }
422 
swap(T & a,T & b)423 template <class T> inline void swap ( T& a, T& b )
424 {
425     T c(a); a=b; b=c;
426 }
427 
alignup(int value,int a)428 inline int alignup(int value, int a) {
429     //if align = 0, return the value. Else, do alignment.
430     return a ? ((((value - 1) / a) + 1) * a) : value;
431 }
432 
aligndown(int value,int a)433 inline int aligndown(int value, int a) {
434     //if align = 0, return the value. Else, do alignment.
435     return a ? ((value) & ~(a-1)) : value;
436 }
437 
438 // FIXME that align should replace the upper one.
align(int value,int a)439 inline int align(int value, int a) {
440     //if align = 0, return the value. Else, do alignment.
441     return a ? ((value + (a-1)) & ~(a-1)) : value;
442 }
443 
444 enum eRotOutFmt {
445     ROT_OUT_FMT_DEFAULT,
446     ROT_OUT_FMT_Y_CRCB_H2V2
447 };
448 
449 template <int ROT_OUT_FMT> struct RotOutFmt;
450 
451 // FIXME, taken from gralloc_priv.h. Need to
452 // put it back as soon as overlay takes place of the old one
453 /* possible formats for 3D content*/
454 enum {
455     HAL_NO_3D                         = 0x0000,
456     HAL_3D_IN_SIDE_BY_SIDE_L_R        = 0x10000,
457     HAL_3D_IN_TOP_BOTTOM              = 0x20000,
458     HAL_3D_IN_INTERLEAVE              = 0x40000,
459     HAL_3D_IN_SIDE_BY_SIDE_R_L        = 0x80000,
460     HAL_3D_OUT_SIDE_BY_SIDE           = 0x1000,
461     HAL_3D_OUT_TOP_BOTTOM             = 0x2000,
462     HAL_3D_OUT_INTERLEAVE             = 0x4000,
463     HAL_3D_OUT_MONOSCOPIC             = 0x8000
464 };
465 
466 enum { HAL_3D_OUT_SBS_MASK =
467     HAL_3D_OUT_SIDE_BY_SIDE >> overlay::utils::SHIFT_OUT_3D,
468     HAL_3D_OUT_TOP_BOT_MASK =
469             HAL_3D_OUT_TOP_BOTTOM >> overlay::utils::SHIFT_OUT_3D,
470     HAL_3D_OUT_INTERL_MASK =
471             HAL_3D_OUT_INTERLEAVE >> overlay::utils::SHIFT_OUT_3D,
472     HAL_3D_OUT_MONOS_MASK =
473             HAL_3D_OUT_MONOSCOPIC >> overlay::utils::SHIFT_OUT_3D
474 };
475 
476 
isYuv(uint32_t format)477 inline bool isYuv(uint32_t format) {
478     switch(format){
479         case MDP_Y_CBCR_H2V1:
480         case MDP_Y_CBCR_H2V2:
481         case MDP_Y_CRCB_H2V2:
482         case MDP_Y_CRCB_H1V1:
483         case MDP_Y_CRCB_H2V1:
484         case MDP_Y_CRCB_H2V2_TILE:
485         case MDP_Y_CBCR_H2V2_TILE:
486         case MDP_Y_CR_CB_H2V2:
487         case MDP_Y_CR_CB_GH2V2:
488         case MDP_Y_CBCR_H2V2_VENUS:
489             return true;
490         default:
491             return false;
492     }
493     return false;
494 }
495 
isRgb(uint32_t format)496 inline bool isRgb(uint32_t format) {
497     switch(format) {
498         case MDP_RGBA_8888:
499         case MDP_BGRA_8888:
500         case MDP_RGBX_8888:
501         case MDP_RGB_565:
502             return true;
503         default:
504             return false;
505     }
506     return false;
507 }
508 
getFormatString(int format)509 inline const char* getFormatString(int format){
510     static const char* const formats[] = {
511         "MDP_RGB_565",
512         "MDP_XRGB_8888",
513         "MDP_Y_CBCR_H2V2",
514         "MDP_Y_CBCR_H2V2_ADRENO",
515         "MDP_ARGB_8888",
516         "MDP_RGB_888",
517         "MDP_Y_CRCB_H2V2",
518         "MDP_YCRYCB_H2V1",
519         "MDP_Y_CRCB_H2V1",
520         "MDP_Y_CBCR_H2V1",
521         "MDP_Y_CRCB_H1V2",
522         "MDP_Y_CBCR_H1V2",
523         "MDP_RGBA_8888",
524         "MDP_BGRA_8888",
525         "MDP_RGBX_8888",
526         "MDP_Y_CRCB_H2V2_TILE",
527         "MDP_Y_CBCR_H2V2_TILE",
528         "MDP_Y_CR_CB_H2V2",
529         "MDP_Y_CR_CB_GH2V2",
530         "MDP_Y_CB_CR_H2V2",
531         "MDP_Y_CRCB_H1V1",
532         "MDP_Y_CBCR_H1V1",
533         "MDP_YCRCB_H1V1",
534         "MDP_YCBCR_H1V1",
535         "MDP_BGR_565",
536         "MDP_BGR_888",
537         "MDP_Y_CBCR_H2V2_VENUS",
538         "MDP_IMGTYPE_LIMIT",
539         "MDP_RGB_BORDERFILL",
540         "MDP_FB_FORMAT",
541         "MDP_IMGTYPE_LIMIT2"
542     };
543     if(format < 0 || format >= (int)(sizeof(formats) / sizeof(formats[0]))) {
544         ALOGE("%s wrong fmt %d", __FUNCTION__, format);
545         return "Unsupported format";
546     }
547     return formats[format];
548 }
549 
dump()550 inline void Whf::dump() const {
551     ALOGE("== Dump WHF w=%d h=%d f=%d s=%d start/end ==",
552             w, h, format, size);
553 }
554 
dump()555 inline void Dim::dump() const {
556     ALOGE("== Dump Dim x=%d y=%d w=%d h=%d start/end ==", x, y, w, h);
557 }
558 
getMdpOrient(eTransform rotation)559 inline int getMdpOrient(eTransform rotation) {
560     ALOGE_IF(DEBUG_OVERLAY, "%s: rot=%d", __FUNCTION__, rotation);
561     switch(rotation)
562     {
563         case OVERLAY_TRANSFORM_0 : return 0;
564         case OVERLAY_TRANSFORM_FLIP_V:  return MDP_FLIP_UD;
565         case OVERLAY_TRANSFORM_FLIP_H:  return MDP_FLIP_LR;
566         case OVERLAY_TRANSFORM_ROT_90:  return MDP_ROT_90;
567         //getMdpOrient will switch the flips if the source is 90 rotated.
568         //Clients in Android dont factor in 90 rotation while deciding flip.
569         case OVERLAY_TRANSFORM_ROT_90_FLIP_V:
570                 return MDP_ROT_90 | MDP_FLIP_LR;
571         case OVERLAY_TRANSFORM_ROT_90_FLIP_H:
572                 return MDP_ROT_90 | MDP_FLIP_UD;
573         case OVERLAY_TRANSFORM_ROT_180: return MDP_ROT_180;
574         case OVERLAY_TRANSFORM_ROT_270: return MDP_ROT_270;
575         default:
576             ALOGE("%s: invalid rotation value (value = 0x%x",
577                     __FUNCTION__, rotation);
578     }
579     return -1;
580 }
581 
582 // FB0
583 template <int CHAN>
getPositionS3DImpl(const Whf & whf)584 inline Dim getPositionS3DImpl(const Whf& whf)
585 {
586     switch (whf.format & OUTPUT_3D_MASK)
587     {
588         case HAL_3D_OUT_SBS_MASK:
589             // x, y, w, h
590             return Dim(0, 0, whf.w/2, whf.h);
591         case HAL_3D_OUT_TOP_BOT_MASK:
592             return Dim(0, 0, whf.w, whf.h/2);
593         case HAL_3D_OUT_MONOS_MASK:
594             return Dim();
595         case HAL_3D_OUT_INTERL_MASK:
596             // FIXME error?
597             ALOGE("%s HAL_3D_OUT_INTERLEAVE_MASK", __FUNCTION__);
598             return Dim();
599         default:
600             ALOGE("%s Unsupported 3D output format %d", __FUNCTION__,
601                     whf.format);
602     }
603     return Dim();
604 }
605 
606 template <>
607 inline Dim getPositionS3DImpl<utils::OV_RIGHT_SPLIT>(const Whf& whf)
608 {
609     switch (whf.format & OUTPUT_3D_MASK)
610     {
611         case HAL_3D_OUT_SBS_MASK:
612             return Dim(whf.w/2, 0, whf.w/2, whf.h);
613         case HAL_3D_OUT_TOP_BOT_MASK:
614             return Dim(0, whf.h/2, whf.w, whf.h/2);
615         case HAL_3D_OUT_MONOS_MASK:
616             return Dim(0, 0, whf.w, whf.h);
617         case HAL_3D_OUT_INTERL_MASK:
618             // FIXME error?
619             ALOGE("%s HAL_3D_OUT_INTERLEAVE_MASK", __FUNCTION__);
620             return Dim();
621         default:
622             ALOGE("%s Unsupported 3D output format %d", __FUNCTION__,
623                     whf.format);
624     }
625     return Dim();
626 }
627 
628 template <int CHAN>
getPositionS3D(const Whf & whf,Dim & out)629 inline bool getPositionS3D(const Whf& whf, Dim& out) {
630     out = getPositionS3DImpl<CHAN>(whf);
631     return (out != Dim());
632 }
633 
634 template <int CHAN>
getCropS3DImpl(const Dim & in,uint32_t fmt)635 inline Dim getCropS3DImpl(const Dim& in, uint32_t fmt) {
636     switch (fmt & INPUT_3D_MASK)
637     {
638         case HAL_3D_IN_SIDE_BY_SIDE_L_R:
639             return Dim(0, 0, in.w/2, in.h);
640         case HAL_3D_IN_SIDE_BY_SIDE_R_L:
641             return Dim(in.w/2, 0, in.w/2, in.h);
642         case HAL_3D_IN_TOP_BOTTOM:
643             return Dim(0, 0, in.w, in.h/2);
644         case HAL_3D_IN_INTERLEAVE:
645             ALOGE("%s HAL_3D_IN_INTERLEAVE", __FUNCTION__);
646             break;
647         default:
648             ALOGE("%s Unsupported 3D format %d", __FUNCTION__, fmt);
649             break;
650     }
651     return Dim();
652 }
653 
654 template <>
655 inline Dim getCropS3DImpl<utils::OV_RIGHT_SPLIT>(const Dim& in, uint32_t fmt) {
656     switch (fmt & INPUT_3D_MASK)
657     {
658         case HAL_3D_IN_SIDE_BY_SIDE_L_R:
659             return Dim(in.w/2, 0, in.w/2, in.h);
660         case HAL_3D_IN_SIDE_BY_SIDE_R_L:
661             return Dim(0, 0, in.w/2, in.h);
662         case HAL_3D_IN_TOP_BOTTOM:
663             return Dim(0, in.h/2, in.w, in.h/2);
664         case HAL_3D_IN_INTERLEAVE:
665             ALOGE("%s HAL_3D_IN_INTERLEAVE", __FUNCTION__);
666             break;
667         default:
668             ALOGE("%s Unsupported 3D format %d", __FUNCTION__, fmt);
669             break;
670     }
671     return Dim();
672 }
673 
674 template <int CHAN>
getCropS3D(const Dim & in,Dim & out,uint32_t fmt)675 inline bool getCropS3D(const Dim& in, Dim& out, uint32_t fmt)
676 {
677     out = getCropS3DImpl<CHAN>(in, fmt);
678     return (out != Dim());
679 }
680 
681 template <class Type>
swapWidthHeight(Type & width,Type & height)682 void swapWidthHeight(Type& width, Type& height) {
683     Type tmp = width;
684     width = height;
685     height = tmp;
686 }
687 
dump(const char * const s)688 inline void ScreenInfo::dump(const char* const s) const {
689     ALOGE("== Dump %s ScreenInfo w=%d h=%d"
690             " bpp=%d stride=%d start/end ==",
691             s, mFBWidth, mFBHeight, mFBbpp, mFBystride);
692 }
693 
openDev(OvFD & fd,int fbnum,const char * const devpath,int flags)694 inline bool openDev(OvFD& fd, int fbnum,
695     const char* const devpath, int flags) {
696     return overlay::open(fd, fbnum, devpath, flags);
697 }
698 
699 template <class T>
even_ceil(T & value)700 inline void even_ceil(T& value) {
701     if(value & 1)
702         value++;
703 }
704 
705 template <class T>
even_floor(T & value)706 inline void even_floor(T& value) {
707     if(value & 1)
708         value--;
709 }
710 
711 void preRotateSource(const eTransform& tr, Whf& whf, Dim& srcCrop);
712 void getDump(char *buf, size_t len, const char *prefix, const mdp_overlay& ov);
713 void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);
714 void getDump(char *buf, size_t len, const char *prefix, const mdp_rect& ov);
715 void getDump(char *buf, size_t len, const char *prefix,
716         const msmfb_overlay_data& ov);
717 void getDump(char *buf, size_t len, const char *prefix, const msmfb_data& ov);
718 void getDump(char *buf, size_t len, const char *prefix,
719         const msm_rotator_img_info& ov);
720 void getDump(char *buf, size_t len, const char *prefix,
721         const msm_rotator_data_info& ov);
722 
723 } // namespace utils ends
724 
725 //--------------------Class Res stuff (namespace overlay only) -----------
726 
727 class Res {
728 public:
729     // /dev/graphics/fb%u
730     static const char* const fbPath;
731     // /dev/msm_rotator
732     static const char* const rotPath;
733     // /sys/class/graphics/fb1/format_3d
734     static const char* const format3DFile;
735     // /sys/class/graphics/fb1/3d_present
736     static const char* const edid3dInfoFile;
737     // /sys/devices/platform/mipi_novatek.0/enable_3d_barrier
738     static const char* const barrierFile;
739 };
740 
741 
742 //--------------------Class OvFD stuff (namespace overlay only) -----------
743 
744 /*
745 * Holds one FD
746 * Dtor will NOT close the underlying FD.
747 * That enables us to copy that object around
748 * */
749 class OvFD {
750 public:
751     /* Ctor */
752     explicit OvFD();
753 
754     /* dtor will NOT close the underlying FD */
755     ~OvFD();
756 
757     /* Open fd using the path given by dev.
758      * return false in failure */
759     bool open(const char* const dev,
760             int flags = O_RDWR);
761 
762     /* populate path */
763     void setPath(const char* const dev);
764 
765     /* Close fd if we have a valid fd. */
766     bool close();
767 
768     /* returns underlying fd.*/
769     int getFD() const;
770 
771     /* returns true if fd is valid */
772     bool valid() const;
773 
774     /* like operator= */
775     void copy(int fd);
776 
777     /* dump the state of the instance */
778     void dump() const;
779 private:
780     /* helper enum for determine valid/invalid fd */
781     enum { INVAL = -1 };
782 
783     /* actual os fd */
784     int mFD;
785 
786     /* path, for debugging */
787     char mPath[utils::MAX_PATH_LEN];
788 };
789 
790 //-------------------Inlines--------------------------
791 
open(OvFD & fd,uint32_t fbnum,const char * const dev,int flags)792 inline bool open(OvFD& fd, uint32_t fbnum, const char* const dev, int flags)
793 {
794     char dev_name[64] = {0};
795     snprintf(dev_name, sizeof(dev_name), dev, fbnum);
796     return fd.open(dev_name, flags);
797 }
798 
OvFD()799 inline OvFD::OvFD() : mFD (INVAL) {
800     mPath[0] = 0;
801 }
802 
~OvFD()803 inline OvFD::~OvFD() {
804     //no op since copy() can be used to share fd, in 3d cases.
805 }
806 
open(const char * const dev,int flags)807 inline bool OvFD::open(const char* const dev, int flags)
808 {
809     mFD = ::open(dev, flags, 0);
810     if (mFD < 0) {
811         // FIXME errno, strerror in bionic?
812         ALOGE("Cant open device %s err=%d", dev, errno);
813         return false;
814     }
815     setPath(dev);
816     return true;
817 }
818 
setPath(const char * const dev)819 inline void OvFD::setPath(const char* const dev)
820 {
821     ::strncpy(mPath, dev, utils::MAX_PATH_LEN);
822 }
823 
close()824 inline bool OvFD::close()
825 {
826     int ret = 0;
827     if(valid()) {
828         ret = ::close(mFD);
829         mFD = INVAL;
830     }
831     return (ret == 0);
832 }
833 
valid()834 inline bool OvFD::valid() const
835 {
836     return (mFD != INVAL);
837 }
838 
getFD()839 inline int OvFD::getFD() const { return mFD; }
840 
copy(int fd)841 inline void OvFD::copy(int fd) {
842     mFD = fd;
843 }
844 
dump()845 inline void OvFD::dump() const
846 {
847     ALOGE("== Dump OvFD fd=%d path=%s start/end ==",
848             mFD, mPath);
849 }
850 
851 //--------------- class OvFD stuff ends ---------------------
852 
853 } // overlay
854 
855 
856 #endif // OVERLAY_UTILS_H
857