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