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