no bug - Import translations from android-l10n r=release a=l10n CLOSED TREE
[gecko.git] / gfx / 2d / Types.h
blobcaefacc116a0c8f366544c2a9d81c94d66f713e7
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_GFX_TYPES_H_
8 #define MOZILLA_GFX_TYPES_H_
10 #include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM_CLASS_WITH_BASE
11 #include "mozilla/EndianUtils.h"
12 #include "mozilla/EnumeratedRange.h"
13 #include "mozilla/MacroArgs.h" // for MOZ_CONCAT
14 #include "mozilla/TypedEnumBits.h"
16 #include <iosfwd> // for ostream
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <optional>
21 namespace mozilla {
22 namespace gfx {
24 typedef float Float;
25 typedef double Double;
27 enum class SurfaceType : int8_t {
28 DATA, /* Data surface - bitmap in memory */
29 D2D1_BITMAP, /* Surface wrapping a ID2D1Bitmap */
30 D2D1_DRAWTARGET, /* Surface made from a D2D draw target */
31 CAIRO, /* Surface wrapping a cairo surface */
32 CAIRO_IMAGE, /* Data surface wrapping a cairo image surface */
33 COREGRAPHICS_IMAGE, /* Surface wrapping a CoreGraphics Image */
34 COREGRAPHICS_CGCONTEXT, /* Surface wrapping a CG context */
35 SKIA, /* Surface wrapping a Skia bitmap */
36 D2D1_1_IMAGE, /* A D2D 1.1 ID2D1Image SourceSurface */
37 RECORDING, /* Surface used for recording */
38 DATA_SHARED, /* Data surface using shared memory */
39 DATA_RECYCLING_SHARED, /* Data surface using shared memory */
40 OFFSET, /* Offset */
41 DATA_ALIGNED, /* Data surface using aligned heap memory */
42 DATA_SHARED_WRAPPER, /* Shared memory mapped in from another process */
43 BLOB_IMAGE, /* Recorded blob image */
44 DATA_MAPPED, /* Data surface wrapping a ScopedMap */
45 WEBGL, /* Surface wrapping a DrawTargetWebgl texture */
48 enum class SurfaceFormat : int8_t {
49 // The following values are named to reflect layout of colors in memory, from
50 // lowest byte to highest byte. The 32-bit value layout depends on machine
51 // endianness.
52 // in-memory 32-bit LE value 32-bit BE value
53 B8G8R8A8, // [BB, GG, RR, AA] 0xAARRGGBB 0xBBGGRRAA
54 B8G8R8X8, // [BB, GG, RR, 00] 0x00RRGGBB 0xBBGGRR00
55 R8G8B8A8, // [RR, GG, BB, AA] 0xAABBGGRR 0xRRGGBBAA
56 R8G8B8X8, // [RR, GG, BB, 00] 0x00BBGGRR 0xRRGGBB00
57 A8R8G8B8, // [AA, RR, GG, BB] 0xBBGGRRAA 0xAARRGGBB
58 X8R8G8B8, // [00, RR, GG, BB] 0xBBGGRR00 0x00RRGGBB
60 R8G8B8,
61 B8G8R8,
63 // The _UINT16 suffix here indicates that the name reflects the layout when
64 // viewed as a uint16_t value. In memory these values are stored using native
65 // endianness.
66 R5G6B5_UINT16, // 0bRRRRRGGGGGGBBBBB
68 // This one is a single-byte, so endianness isn't an issue.
69 A8,
70 A16,
72 R8G8,
73 R16G16,
75 // These ones are their own special cases.
76 YUV,
77 NV12, // YUV 4:2:0 image with a plane of 8 bit Y samples followed by
78 // an interleaved U/V plane containing 8 bit 2x2 subsampled
79 // colour difference samples.
80 P016, // Similar to NV12, but with 16 bits plane values
81 P010, // Identical to P016 but the 6 least significant bits are 0.
82 // With DXGI in theory entirely compatible, however practice has
83 // shown that it's not the case.
84 YUV422, // Single plane YUV 4:2:2 interleaved as Y`0 Cb Y`1 Cr.
85 HSV,
86 Lab,
87 Depth,
89 // This represents the unknown format.
90 UNKNOWN, // TODO: Replace uses with Maybe<SurfaceFormat>.
92 // The following values are endian-independent synonyms. The _UINT32 suffix
93 // indicates that the name reflects the layout when viewed as a uint32_t
94 // value.
95 #if MOZ_LITTLE_ENDIAN()
96 A8R8G8B8_UINT32 = B8G8R8A8, // 0xAARRGGBB
97 X8R8G8B8_UINT32 = B8G8R8X8, // 0x00RRGGBB
98 #elif MOZ_BIG_ENDIAN()
99 A8R8G8B8_UINT32 = A8R8G8B8, // 0xAARRGGBB
100 X8R8G8B8_UINT32 = X8R8G8B8, // 0x00RRGGBB
101 #else
102 # error "bad endianness"
103 #endif
105 // The following values are OS and endian-independent synonyms.
107 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
108 // can make this use R8B8G8A8 and R8B8G8X8 for non-Windows platforms.
109 OS_RGBA = A8R8G8B8_UINT32,
110 OS_RGBX = X8R8G8B8_UINT32
113 struct SurfaceFormatInfo {
114 bool hasColor;
115 bool hasAlpha;
116 bool isYuv;
117 std::optional<uint8_t> bytesPerPixel;
119 inline std::optional<SurfaceFormatInfo> Info(const SurfaceFormat aFormat) {
120 auto info = SurfaceFormatInfo{};
122 switch (aFormat) {
123 case SurfaceFormat::B8G8R8A8:
124 case SurfaceFormat::R8G8B8A8:
125 case SurfaceFormat::A8R8G8B8:
126 info.hasColor = true;
127 info.hasAlpha = true;
128 break;
130 case SurfaceFormat::B8G8R8X8:
131 case SurfaceFormat::R8G8B8X8:
132 case SurfaceFormat::X8R8G8B8:
133 case SurfaceFormat::R8G8B8:
134 case SurfaceFormat::B8G8R8:
135 case SurfaceFormat::R5G6B5_UINT16:
136 case SurfaceFormat::R8G8:
137 case SurfaceFormat::R16G16:
138 case SurfaceFormat::HSV:
139 case SurfaceFormat::Lab:
140 info.hasColor = true;
141 info.hasAlpha = false;
142 break;
144 case SurfaceFormat::A8:
145 case SurfaceFormat::A16:
146 info.hasColor = false;
147 info.hasAlpha = true;
148 break;
150 case SurfaceFormat::YUV:
151 case SurfaceFormat::NV12:
152 case SurfaceFormat::P016:
153 case SurfaceFormat::P010:
154 case SurfaceFormat::YUV422:
155 info.hasColor = true;
156 info.hasAlpha = false;
157 info.isYuv = true;
158 break;
160 case SurfaceFormat::Depth:
161 info.hasColor = false;
162 info.hasAlpha = false;
163 info.isYuv = false;
164 break;
166 case SurfaceFormat::UNKNOWN:
167 break;
170 // -
171 // bytesPerPixel
173 switch (aFormat) {
174 case SurfaceFormat::B8G8R8A8:
175 case SurfaceFormat::R8G8B8A8:
176 case SurfaceFormat::A8R8G8B8:
177 case SurfaceFormat::B8G8R8X8:
178 case SurfaceFormat::R8G8B8X8:
179 case SurfaceFormat::X8R8G8B8:
180 case SurfaceFormat::R16G16:
181 info.bytesPerPixel = 4;
182 break;
184 case SurfaceFormat::R8G8B8:
185 case SurfaceFormat::B8G8R8:
186 info.bytesPerPixel = 3;
187 break;
189 case SurfaceFormat::R5G6B5_UINT16:
190 case SurfaceFormat::R8G8:
191 case SurfaceFormat::A16:
192 case SurfaceFormat::Depth: // uint16_t
193 info.bytesPerPixel = 2;
194 break;
196 case SurfaceFormat::A8:
197 info.bytesPerPixel = 1;
198 break;
200 case SurfaceFormat::HSV:
201 case SurfaceFormat::Lab:
202 info.bytesPerPixel = 3 * sizeof(float);
203 break;
205 case SurfaceFormat::YUV:
206 case SurfaceFormat::NV12:
207 case SurfaceFormat::P016:
208 case SurfaceFormat::P010:
209 case SurfaceFormat::YUV422:
210 case SurfaceFormat::UNKNOWN:
211 break; // No bytesPerPixel per se.
214 // -
216 if (aFormat == SurfaceFormat::UNKNOWN) {
217 return {};
219 return info;
222 std::ostream& operator<<(std::ostream& aOut, const SurfaceFormat& aFormat);
224 // Represents the bit-shifts required to access color channels when the layout
225 // is viewed as a uint32_t value.
226 enum class SurfaceFormatBit : uint32_t {
227 #if MOZ_LITTLE_ENDIAN()
228 R8G8B8A8_R = 0,
229 R8G8B8A8_G = 8,
230 R8G8B8A8_B = 16,
231 R8G8B8A8_A = 24,
232 #elif MOZ_BIG_ENDIAN()
233 R8G8B8A8_A = 0,
234 R8G8B8A8_B = 8,
235 R8G8B8A8_G = 16,
236 R8G8B8A8_R = 24,
237 #else
238 # error "bad endianness"
239 #endif
241 // The following values are endian-independent for A8R8G8B8_UINT32.
242 A8R8G8B8_UINT32_B = 0,
243 A8R8G8B8_UINT32_G = 8,
244 A8R8G8B8_UINT32_R = 16,
245 A8R8G8B8_UINT32_A = 24,
247 // The following values are OS and endian-independent.
249 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
250 // can make this use R8G8B8A8_X for non-Windows platforms.
251 OS_R = A8R8G8B8_UINT32_R,
252 OS_G = A8R8G8B8_UINT32_G,
253 OS_B = A8R8G8B8_UINT32_B,
254 OS_A = A8R8G8B8_UINT32_A,
257 inline uint32_t operator<<(uint8_t a, SurfaceFormatBit b) {
258 return a << static_cast<uint32_t>(b);
261 inline uint32_t operator>>(uint32_t a, SurfaceFormatBit b) {
262 return a >> static_cast<uint32_t>(b);
265 static inline int BytesPerPixel(SurfaceFormat aFormat) {
266 // TODO: return Info(aFormat).value().bytesPerPixel.value();
267 switch (aFormat) {
268 case SurfaceFormat::A8:
269 return 1;
270 case SurfaceFormat::R5G6B5_UINT16:
271 case SurfaceFormat::A16:
272 return 2;
273 case SurfaceFormat::R8G8B8:
274 case SurfaceFormat::B8G8R8:
275 return 3;
276 case SurfaceFormat::HSV:
277 case SurfaceFormat::Lab:
278 return 3 * sizeof(float);
279 case SurfaceFormat::Depth:
280 return sizeof(uint16_t);
281 default:
282 return 4;
286 inline bool IsOpaque(SurfaceFormat aFormat) {
287 // TODO: return Info(aFormat).value().hasAlpha;
288 switch (aFormat) {
289 case SurfaceFormat::B8G8R8X8:
290 case SurfaceFormat::R8G8B8X8:
291 case SurfaceFormat::X8R8G8B8:
292 case SurfaceFormat::R5G6B5_UINT16:
293 case SurfaceFormat::R8G8B8:
294 case SurfaceFormat::B8G8R8:
295 case SurfaceFormat::R8G8:
296 case SurfaceFormat::HSV:
297 case SurfaceFormat::Lab:
298 case SurfaceFormat::Depth:
299 case SurfaceFormat::YUV:
300 case SurfaceFormat::NV12:
301 case SurfaceFormat::P010:
302 case SurfaceFormat::P016:
303 case SurfaceFormat::YUV422:
304 return true;
305 default:
306 return false;
310 // These are standardized Coding-independent Code Points
311 // See [Rec. ITU-T H.273
312 // (12/2016)](https://www.itu.int/rec/T-REC-H.273-201612-I/en)
314 // We deliberately use an unscoped enum with fixed uint8_t representation since
315 // all possible values [0, 255] are legal, but it's unwieldy to declare 200+
316 // "RESERVED" enumeration values. Having a fixed underlying type avoids any
317 // potential UB and avoids the need for a cast when passing these values across
318 // FFI to functions like qcms_profile_create_cicp.
319 namespace CICP {
320 enum ColourPrimaries : uint8_t {
321 CP_RESERVED_MIN = 0, // 0, 3, [13, 21], [23, 255] are all reserved
322 CP_BT709 = 1,
323 CP_UNSPECIFIED = 2,
324 CP_BT470M = 4,
325 CP_BT470BG = 5,
326 CP_BT601 = 6,
327 CP_SMPTE240 = 7,
328 CP_GENERIC_FILM = 8,
329 CP_BT2020 = 9,
330 CP_XYZ = 10,
331 CP_SMPTE431 = 11,
332 CP_SMPTE432 = 12,
333 CP_EBU3213 = 22,
336 inline bool IsReserved(ColourPrimaries aIn) {
337 switch (aIn) {
338 case CP_BT709:
339 case CP_UNSPECIFIED:
340 case CP_BT470M:
341 case CP_BT470BG:
342 case CP_BT601:
343 case CP_SMPTE240:
344 case CP_GENERIC_FILM:
345 case CP_BT2020:
346 case CP_XYZ:
347 case CP_SMPTE431:
348 case CP_SMPTE432:
349 case CP_EBU3213:
350 return false;
351 default:
352 return true;
356 enum TransferCharacteristics : uint8_t {
357 TC_RESERVED_MIN = 0, // 0, 3, [19, 255] are all reserved
358 TC_BT709 = 1,
359 TC_UNSPECIFIED = 2,
360 TC_BT470M = 4,
361 TC_BT470BG = 5,
362 TC_BT601 = 6,
363 TC_SMPTE240 = 7,
364 TC_LINEAR = 8,
365 TC_LOG_100 = 9,
366 TC_LOG_100_SQRT10 = 10,
367 TC_IEC61966 = 11,
368 TC_BT_1361 = 12,
369 TC_SRGB = 13,
370 TC_BT2020_10BIT = 14,
371 TC_BT2020_12BIT = 15,
372 TC_SMPTE2084 = 16,
373 TC_SMPTE428 = 17,
374 TC_HLG = 18,
377 inline bool IsReserved(TransferCharacteristics aIn) {
378 switch (aIn) {
379 case TC_BT709:
380 case TC_UNSPECIFIED:
381 case TC_BT470M:
382 case TC_BT470BG:
383 case TC_BT601:
384 case TC_SMPTE240:
385 case TC_LINEAR:
386 case TC_LOG_100:
387 case TC_LOG_100_SQRT10:
388 case TC_IEC61966:
389 case TC_BT_1361:
390 case TC_SRGB:
391 case TC_BT2020_10BIT:
392 case TC_BT2020_12BIT:
393 case TC_SMPTE2084:
394 case TC_SMPTE428:
395 case TC_HLG:
396 return false;
397 default:
398 return true;
402 enum MatrixCoefficients : uint8_t {
403 MC_IDENTITY = 0,
404 MC_BT709 = 1,
405 MC_UNSPECIFIED = 2,
406 MC_RESERVED_MIN = 3, // 3, [15, 255] are all reserved
407 MC_FCC = 4,
408 MC_BT470BG = 5,
409 MC_BT601 = 6,
410 MC_SMPTE240 = 7,
411 MC_YCGCO = 8,
412 MC_BT2020_NCL = 9,
413 MC_BT2020_CL = 10,
414 MC_SMPTE2085 = 11,
415 MC_CHROMAT_NCL = 12,
416 MC_CHROMAT_CL = 13,
417 MC_ICTCP = 14,
420 inline bool IsReserved(MatrixCoefficients aIn) {
421 switch (aIn) {
422 case MC_IDENTITY:
423 case MC_BT709:
424 case MC_UNSPECIFIED:
425 case MC_RESERVED_MIN:
426 case MC_FCC:
427 case MC_BT470BG:
428 case MC_BT601:
429 case MC_SMPTE240:
430 case MC_YCGCO:
431 case MC_BT2020_NCL:
432 case MC_BT2020_CL:
433 case MC_SMPTE2085:
434 case MC_CHROMAT_NCL:
435 case MC_CHROMAT_CL:
436 case MC_ICTCP:
437 return false;
438 default:
439 return true;
442 } // namespace CICP
444 // The matrix coeffiecients used for YUV to RGB conversion.
445 enum class YUVColorSpace : uint8_t {
446 BT601,
447 BT709,
448 BT2020,
449 Identity, // Todo: s/YUVColorSpace/ColorSpace/, s/Identity/SRGB/
450 Default = BT709,
451 _First = BT601,
452 _Last = Identity,
455 enum class ColorDepth : uint8_t {
456 COLOR_8,
457 COLOR_10,
458 COLOR_12,
459 COLOR_16,
460 _First = COLOR_8,
461 _Last = COLOR_16,
464 enum class TransferFunction : uint8_t {
465 BT709,
466 SRGB,
468 HLG,
469 _First = BT709,
470 _Last = HLG,
471 Default = BT709,
474 enum class ColorRange : uint8_t {
475 LIMITED,
476 FULL,
477 _First = LIMITED,
478 _Last = FULL,
481 // Really "YcbcrColorColorSpace"
482 enum class YUVRangedColorSpace : uint8_t {
483 BT601_Narrow = 0,
484 BT601_Full,
485 BT709_Narrow,
486 BT709_Full,
487 BT2020_Narrow,
488 BT2020_Full,
489 GbrIdentity,
491 _First = BT601_Narrow,
492 _Last = GbrIdentity,
493 Default = BT709_Narrow,
496 // I can either come up with a longer "very clever" name that doesn't conflict
497 // with FilterSupport.h, embrace and expand FilterSupport, or rename the old
498 // one.
499 // Some times Worse Is Better.
500 enum class ColorSpace2 : uint8_t {
501 Display,
502 UNKNOWN = Display, // We feel sufficiently bad about this TODO.
503 SRGB,
504 DISPLAY_P3,
505 BT601_525, // aka smpte170m NTSC
506 BT709, // Same gamut as SRGB, but different gamma.
507 BT601_625 =
508 BT709, // aka bt470bg PAL. Basically BT709, just Xg is 0.290 not 0.300.
509 BT2020,
510 _First = Display,
511 _Last = BT2020,
514 inline ColorSpace2 ToColorSpace2(const YUVColorSpace in) {
515 switch (in) {
516 case YUVColorSpace::BT601:
517 return ColorSpace2::BT601_525;
518 case YUVColorSpace::BT709:
519 return ColorSpace2::BT709;
520 case YUVColorSpace::BT2020:
521 return ColorSpace2::BT2020;
522 case YUVColorSpace::Identity:
523 return ColorSpace2::SRGB;
525 MOZ_ASSERT_UNREACHABLE();
528 inline YUVColorSpace ToYUVColorSpace(const ColorSpace2 in) {
529 switch (in) {
530 case ColorSpace2::BT601_525:
531 return YUVColorSpace::BT601;
532 case ColorSpace2::BT709:
533 return YUVColorSpace::BT709;
534 case ColorSpace2::BT2020:
535 return YUVColorSpace::BT2020;
536 case ColorSpace2::SRGB:
537 return YUVColorSpace::Identity;
539 case ColorSpace2::UNKNOWN:
540 case ColorSpace2::DISPLAY_P3:
541 MOZ_CRASH("Bad ColorSpace2 for ToYUVColorSpace");
543 MOZ_ASSERT_UNREACHABLE();
546 struct FromYUVRangedColorSpaceT final {
547 const YUVColorSpace space;
548 const ColorRange range;
551 inline FromYUVRangedColorSpaceT FromYUVRangedColorSpace(
552 const YUVRangedColorSpace s) {
553 switch (s) {
554 case YUVRangedColorSpace::BT601_Narrow:
555 return {YUVColorSpace::BT601, ColorRange::LIMITED};
556 case YUVRangedColorSpace::BT601_Full:
557 return {YUVColorSpace::BT601, ColorRange::FULL};
559 case YUVRangedColorSpace::BT709_Narrow:
560 return {YUVColorSpace::BT709, ColorRange::LIMITED};
561 case YUVRangedColorSpace::BT709_Full:
562 return {YUVColorSpace::BT709, ColorRange::FULL};
564 case YUVRangedColorSpace::BT2020_Narrow:
565 return {YUVColorSpace::BT2020, ColorRange::LIMITED};
566 case YUVRangedColorSpace::BT2020_Full:
567 return {YUVColorSpace::BT2020, ColorRange::FULL};
569 case YUVRangedColorSpace::GbrIdentity:
570 return {YUVColorSpace::Identity, ColorRange::FULL};
572 MOZ_CRASH("bad YUVRangedColorSpace");
575 // Todo: This should go in the CPP.
576 inline YUVRangedColorSpace ToYUVRangedColorSpace(const YUVColorSpace space,
577 const ColorRange range) {
578 bool narrow;
579 switch (range) {
580 case ColorRange::FULL:
581 narrow = false;
582 break;
583 case ColorRange::LIMITED:
584 narrow = true;
585 break;
588 switch (space) {
589 case YUVColorSpace::Identity:
590 MOZ_ASSERT(range == ColorRange::FULL);
591 return YUVRangedColorSpace::GbrIdentity;
593 case YUVColorSpace::BT601:
594 return narrow ? YUVRangedColorSpace::BT601_Narrow
595 : YUVRangedColorSpace::BT601_Full;
597 case YUVColorSpace::BT709:
598 return narrow ? YUVRangedColorSpace::BT709_Narrow
599 : YUVRangedColorSpace::BT709_Full;
601 case YUVColorSpace::BT2020:
602 return narrow ? YUVRangedColorSpace::BT2020_Narrow
603 : YUVRangedColorSpace::BT2020_Full;
605 MOZ_CRASH("bad YUVColorSpace");
608 template <typename DescriptorT>
609 inline YUVRangedColorSpace GetYUVRangedColorSpace(const DescriptorT& d) {
610 return ToYUVRangedColorSpace(d.yUVColorSpace(), d.colorRange());
613 static inline SurfaceFormat SurfaceFormatForColorDepth(ColorDepth aColorDepth) {
614 SurfaceFormat format = SurfaceFormat::A8;
615 switch (aColorDepth) {
616 case ColorDepth::COLOR_8:
617 break;
618 case ColorDepth::COLOR_10:
619 case ColorDepth::COLOR_12:
620 case ColorDepth::COLOR_16:
621 format = SurfaceFormat::A16;
622 break;
624 return format;
627 static inline uint8_t BitDepthForColorDepth(ColorDepth aColorDepth) {
628 uint8_t depth = 8;
629 switch (aColorDepth) {
630 case ColorDepth::COLOR_8:
631 break;
632 case ColorDepth::COLOR_10:
633 depth = 10;
634 break;
635 case ColorDepth::COLOR_12:
636 depth = 12;
637 break;
638 case ColorDepth::COLOR_16:
639 depth = 16;
640 break;
642 return depth;
645 static inline ColorDepth ColorDepthForBitDepth(uint8_t aBitDepth) {
646 ColorDepth depth = ColorDepth::COLOR_8;
647 switch (aBitDepth) {
648 case 8:
649 break;
650 case 10:
651 depth = ColorDepth::COLOR_10;
652 break;
653 case 12:
654 depth = ColorDepth::COLOR_12;
655 break;
656 case 16:
657 depth = ColorDepth::COLOR_16;
658 break;
660 return depth;
663 // 10 and 12 bits color depth image are using 16 bits integers for storage
664 // As such we need to rescale the value from 10 or 12 bits to 16.
665 static inline uint32_t RescalingFactorForColorDepth(ColorDepth aColorDepth) {
666 uint32_t factor = 1;
667 switch (aColorDepth) {
668 case ColorDepth::COLOR_8:
669 break;
670 case ColorDepth::COLOR_10:
671 factor = 64;
672 break;
673 case ColorDepth::COLOR_12:
674 factor = 16;
675 break;
676 case ColorDepth::COLOR_16:
677 break;
679 return factor;
682 enum class ChromaSubsampling : uint8_t {
683 FULL,
684 HALF_WIDTH,
685 HALF_WIDTH_AND_HEIGHT,
686 _First = FULL,
687 _Last = HALF_WIDTH_AND_HEIGHT,
690 template <typename T>
691 static inline T ChromaSize(const T& aYSize, ChromaSubsampling aSubsampling) {
692 switch (aSubsampling) {
693 case ChromaSubsampling::FULL:
694 return aYSize;
695 case ChromaSubsampling::HALF_WIDTH:
696 return T((aYSize.width + 1) / 2, aYSize.height);
697 case ChromaSubsampling::HALF_WIDTH_AND_HEIGHT:
698 return T((aYSize.width + 1) / 2, (aYSize.height + 1) / 2);
700 MOZ_CRASH("bad ChromaSubsampling");
703 enum class FilterType : int8_t {
704 BLEND = 0,
705 TRANSFORM,
706 MORPHOLOGY,
707 COLOR_MATRIX,
708 FLOOD,
709 TILE,
710 TABLE_TRANSFER,
711 DISCRETE_TRANSFER,
712 LINEAR_TRANSFER,
713 GAMMA_TRANSFER,
714 CONVOLVE_MATRIX,
715 DISPLACEMENT_MAP,
716 TURBULENCE,
717 ARITHMETIC_COMBINE,
718 COMPOSITE,
719 DIRECTIONAL_BLUR,
720 GAUSSIAN_BLUR,
721 POINT_DIFFUSE,
722 POINT_SPECULAR,
723 SPOT_DIFFUSE,
724 SPOT_SPECULAR,
725 DISTANT_DIFFUSE,
726 DISTANT_SPECULAR,
727 CROP,
728 PREMULTIPLY,
729 UNPREMULTIPLY,
730 OPACITY
733 enum class DrawTargetType : int8_t {
734 SOFTWARE_RASTER = 0,
735 HARDWARE_RASTER,
736 VECTOR
739 enum class BackendType : int8_t {
740 NONE = 0,
741 DIRECT2D, // Used for version independent D2D objects.
742 CAIRO,
743 SKIA,
744 RECORDING,
745 DIRECT2D1_1,
746 WEBRENDER_TEXT,
747 WEBGL,
749 // Add new entries above this line.
750 BACKEND_LAST
753 enum class RecorderType : int8_t {
754 UNKNOWN,
755 PRIVATE,
756 MEMORY,
757 CANVAS,
758 PRFILEDESC,
759 WEBRENDER
762 enum class FontType : int8_t {
763 DWRITE,
764 GDI,
765 MAC,
766 FONTCONFIG,
767 FREETYPE,
768 UNKNOWN
771 enum class NativeSurfaceType : int8_t {
772 D3D10_TEXTURE,
773 CAIRO_CONTEXT,
774 CGCONTEXT,
775 CGCONTEXT_ACCELERATED,
776 OPENGL_TEXTURE,
777 WEBGL_CONTEXT
780 enum class FontStyle : int8_t { NORMAL, ITALIC, BOLD, BOLD_ITALIC };
782 enum class FontHinting : int8_t { NONE, LIGHT, NORMAL, FULL };
784 enum class CompositionOp : int8_t {
785 OP_CLEAR,
786 OP_OVER,
787 OP_ADD,
788 OP_ATOP,
789 OP_OUT,
790 OP_IN,
791 OP_SOURCE,
792 OP_DEST_IN,
793 OP_DEST_OUT,
794 OP_DEST_OVER,
795 OP_DEST_ATOP,
796 OP_XOR,
797 OP_MULTIPLY,
798 OP_SCREEN,
799 OP_OVERLAY,
800 OP_DARKEN,
801 OP_LIGHTEN,
802 OP_COLOR_DODGE,
803 OP_COLOR_BURN,
804 OP_HARD_LIGHT,
805 OP_SOFT_LIGHT,
806 OP_DIFFERENCE,
807 OP_EXCLUSION,
808 OP_HUE,
809 OP_SATURATION,
810 OP_COLOR,
811 OP_LUMINOSITY,
812 OP_COUNT
815 enum class Axis : int8_t { X_AXIS, Y_AXIS, BOTH };
817 enum class ExtendMode : int8_t {
818 CLAMP, // Do not repeat
819 REPEAT, // Repeat in both axis
820 REPEAT_X, // Only X axis
821 REPEAT_Y, // Only Y axis
822 REFLECT // Mirror the image
825 enum class FillRule : int8_t { FILL_WINDING, FILL_EVEN_ODD };
827 enum class AntialiasMode : int8_t { NONE, GRAY, SUBPIXEL, DEFAULT };
829 // See https://en.wikipedia.org/wiki/Texture_filtering
830 enum class SamplingFilter : int8_t {
831 GOOD,
832 LINEAR,
833 POINT,
834 SENTINEL // one past the last valid value
837 std::ostream& operator<<(std::ostream& aOut, const SamplingFilter& aFilter);
839 // clang-format off
840 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(PatternType, int8_t, (
841 COLOR,
842 SURFACE,
843 LINEAR_GRADIENT,
844 RADIAL_GRADIENT,
845 CONIC_GRADIENT
847 // clang-format on
849 enum class JoinStyle : int8_t {
850 BEVEL,
851 ROUND,
852 MITER, //!< Mitered if within the miter limit, else, if the backed supports
853 //!< it (D2D), the miter is clamped. If the backend does not support
854 //!< miter clamping the behavior is as for MITER_OR_BEVEL.
855 MITER_OR_BEVEL //!< Mitered if within the miter limit, else beveled.
858 enum class CapStyle : int8_t { BUTT, ROUND, SQUARE };
860 enum class SamplingBounds : int8_t { UNBOUNDED, BOUNDED };
862 // Moz2d version for SVG mask types
863 enum class LuminanceType : int8_t {
864 LUMINANCE,
865 LINEARRGB,
868 /* Color is stored in non-premultiplied form in sRGB color space */
869 struct sRGBColor {
870 public:
871 constexpr sRGBColor() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {}
872 constexpr sRGBColor(Float aR, Float aG, Float aB, Float aA)
873 : r(aR), g(aG), b(aB), a(aA) {}
874 constexpr sRGBColor(Float aR, Float aG, Float aB)
875 : r(aR), g(aG), b(aB), a(1.0f) {}
877 static constexpr sRGBColor White(float aA) {
878 return sRGBColor(1.f, 1.f, 1.f, aA);
881 static constexpr sRGBColor Black(float aA) {
882 return sRGBColor(0.f, 0.f, 0.f, aA);
885 static constexpr sRGBColor OpaqueWhite() { return White(1.f); }
887 static constexpr sRGBColor OpaqueBlack() { return Black(1.f); }
889 static constexpr sRGBColor FromU8(uint8_t aR, uint8_t aG, uint8_t aB,
890 uint8_t aA) {
891 return sRGBColor(float(aR) / 255.f, float(aG) / 255.f, float(aB) / 255.f,
892 float(aA) / 255.f);
895 static constexpr sRGBColor FromABGR(uint32_t aColor) {
896 return sRGBColor(((aColor >> 0) & 0xff) * (1.0f / 255.0f),
897 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
898 ((aColor >> 16) & 0xff) * (1.0f / 255.0f),
899 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
902 // The "Unusual" prefix is to avoid unintentionally using this function when
903 // FromABGR(), which is much more common, is needed.
904 static constexpr sRGBColor UnusualFromARGB(uint32_t aColor) {
905 return sRGBColor(((aColor >> 16) & 0xff) * (1.0f / 255.0f),
906 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
907 ((aColor >> 0) & 0xff) * (1.0f / 255.0f),
908 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
911 constexpr uint32_t ToABGR() const {
912 return uint32_t(r * 255.0f) | uint32_t(g * 255.0f) << 8 |
913 uint32_t(b * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
916 constexpr sRGBColor Premultiplied() const {
917 return sRGBColor(r * a, g * a, b * a, a);
920 constexpr sRGBColor Unpremultiplied() const {
921 return a > 0.f ? sRGBColor(r / a, g / a, b / a, a) : *this;
924 // The "Unusual" prefix is to avoid unintentionally using this function when
925 // ToABGR(), which is much more common, is needed.
926 uint32_t UnusualToARGB() const {
927 return uint32_t(b * 255.0f) | uint32_t(g * 255.0f) << 8 |
928 uint32_t(r * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
931 bool operator==(const sRGBColor& aColor) const {
932 return r == aColor.r && g == aColor.g && b == aColor.b && a == aColor.a;
935 bool operator!=(const sRGBColor& aColor) const { return !(*this == aColor); }
937 Float r, g, b, a;
940 /* Color is stored in non-premultiplied form in device color space */
941 struct DeviceColor {
942 public:
943 DeviceColor() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {}
944 DeviceColor(Float aR, Float aG, Float aB, Float aA)
945 : r(aR), g(aG), b(aB), a(aA) {}
946 DeviceColor(Float aR, Float aG, Float aB) : r(aR), g(aG), b(aB), a(1.0f) {}
948 /* The following Mask* variants are helpers used to make it clear when a
949 * particular color is being used for masking purposes. These masks should
950 * never be colored managed. */
951 static DeviceColor Mask(float aC, float aA) {
952 return DeviceColor(aC, aC, aC, aA);
955 static DeviceColor MaskWhite(float aA) { return Mask(1.f, aA); }
957 static DeviceColor MaskBlack(float aA) { return Mask(0.f, aA); }
959 static DeviceColor MaskOpaqueWhite() { return MaskWhite(1.f); }
961 static DeviceColor MaskOpaqueBlack() { return MaskBlack(1.f); }
963 static DeviceColor FromU8(uint8_t aR, uint8_t aG, uint8_t aB, uint8_t aA) {
964 return DeviceColor(float(aR) / 255.f, float(aG) / 255.f, float(aB) / 255.f,
965 float(aA) / 255.f);
968 static DeviceColor FromABGR(uint32_t aColor) {
969 DeviceColor newColor(((aColor >> 0) & 0xff) * (1.0f / 255.0f),
970 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
971 ((aColor >> 16) & 0xff) * (1.0f / 255.0f),
972 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
974 return newColor;
977 // The "Unusual" prefix is to avoid unintentionally using this function when
978 // FromABGR(), which is much more common, is needed.
979 static DeviceColor UnusualFromARGB(uint32_t aColor) {
980 DeviceColor newColor(((aColor >> 16) & 0xff) * (1.0f / 255.0f),
981 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
982 ((aColor >> 0) & 0xff) * (1.0f / 255.0f),
983 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
985 return newColor;
988 uint32_t ToABGR() const {
989 return uint32_t(r * 255.0f) | uint32_t(g * 255.0f) << 8 |
990 uint32_t(b * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
993 // The "Unusual" prefix is to avoid unintentionally using this function when
994 // ToABGR(), which is much more common, is needed.
995 uint32_t UnusualToARGB() const {
996 return uint32_t(b * 255.0f) | uint32_t(g * 255.0f) << 8 |
997 uint32_t(r * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
1000 bool operator==(const DeviceColor& aColor) const {
1001 return r == aColor.r && g == aColor.g && b == aColor.b && a == aColor.a;
1004 bool operator!=(const DeviceColor& aColor) const {
1005 return !(*this == aColor);
1008 friend std::ostream& operator<<(std::ostream& aOut,
1009 const DeviceColor& aColor);
1011 Float r, g, b, a;
1014 struct GradientStop {
1015 bool operator<(const GradientStop& aOther) const {
1016 return offset < aOther.offset;
1019 Float offset;
1020 DeviceColor color;
1023 enum class JobStatus { Complete, Wait, Yield, Error };
1025 } // namespace gfx
1026 } // namespace mozilla
1028 // XXX: temporary
1029 typedef mozilla::gfx::SurfaceFormat gfxImageFormat;
1031 #if defined(XP_WIN) && defined(MOZ_GFX)
1032 # ifdef GFX2D_INTERNAL
1033 # define GFX2D_API __declspec(dllexport)
1034 # else
1035 # define GFX2D_API __declspec(dllimport)
1036 # endif
1037 #else
1038 # define GFX2D_API
1039 #endif
1041 namespace mozilla {
1043 // Side constants for use in various places.
1044 enum Side : uint8_t { eSideTop, eSideRight, eSideBottom, eSideLeft };
1046 std::ostream& operator<<(std::ostream&, const mozilla::Side&);
1048 constexpr auto AllPhysicalSides() {
1049 return mozilla::MakeInclusiveEnumeratedRange(eSideTop, eSideLeft);
1052 enum class SideBits {
1053 eNone = 0,
1054 eTop = 1 << eSideTop,
1055 eRight = 1 << eSideRight,
1056 eBottom = 1 << eSideBottom,
1057 eLeft = 1 << eSideLeft,
1058 eTopBottom = SideBits::eTop | SideBits::eBottom,
1059 eLeftRight = SideBits::eLeft | SideBits::eRight,
1060 eAll = SideBits::eTopBottom | SideBits::eLeftRight
1063 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SideBits)
1065 inline constexpr SideBits SideToSideBit(mozilla::Side aSide) {
1066 return SideBits(1 << aSide);
1069 enum Corner : uint8_t {
1070 // This order is important!
1071 eCornerTopLeft = 0,
1072 eCornerTopRight = 1,
1073 eCornerBottomRight = 2,
1074 eCornerBottomLeft = 3
1077 // RectCornerRadii::radii depends on this value. It is not being added to
1078 // Corner because we want to lift the responsibility to handle it in the
1079 // switch-case.
1080 constexpr int eCornerCount = 4;
1082 constexpr auto AllPhysicalCorners() {
1083 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeft,
1084 eCornerBottomLeft);
1087 // Indices into "half corner" arrays (nsStyleCorners e.g.)
1088 enum HalfCorner : uint8_t {
1089 // This order is important!
1090 eCornerTopLeftX = 0,
1091 eCornerTopLeftY = 1,
1092 eCornerTopRightX = 2,
1093 eCornerTopRightY = 3,
1094 eCornerBottomRightX = 4,
1095 eCornerBottomRightY = 5,
1096 eCornerBottomLeftX = 6,
1097 eCornerBottomLeftY = 7
1100 constexpr auto AllPhysicalHalfCorners() {
1101 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeftX,
1102 eCornerBottomLeftY);
1105 // The result of these conversion functions are exhaustively checked in
1106 // nsFrame.cpp, which also serves as usage examples.
1108 constexpr bool HalfCornerIsX(HalfCorner aHalfCorner) {
1109 return !(aHalfCorner % 2);
1112 constexpr Corner HalfToFullCorner(HalfCorner aHalfCorner) {
1113 return Corner(aHalfCorner / 2);
1116 constexpr HalfCorner FullToHalfCorner(Corner aCorner, bool aIsVertical) {
1117 return HalfCorner(aCorner * 2 + aIsVertical);
1120 constexpr bool SideIsVertical(mozilla::Side aSide) { return aSide % 2; }
1122 // @param aIsSecond when true, return the clockwise second of the two
1123 // corners associated with aSide. For example, with aSide = eSideBottom the
1124 // result is eCornerBottomRight when aIsSecond is false, and
1125 // eCornerBottomLeft when aIsSecond is true.
1126 constexpr Corner SideToFullCorner(mozilla::Side aSide, bool aIsSecond) {
1127 return Corner((aSide + aIsSecond) % 4);
1130 // @param aIsSecond see SideToFullCorner.
1131 // @param aIsParallel return the half-corner that is parallel with aSide
1132 // when aIsParallel is true. For example with aSide=eSideTop, aIsSecond=true
1133 // the result is eCornerTopRightX when aIsParallel is true, and
1134 // eCornerTopRightY when aIsParallel is false (because "X" is parallel with
1135 // eSideTop/eSideBottom, similarly "Y" is parallel with
1136 // eSideLeft/eSideRight)
1137 constexpr HalfCorner SideToHalfCorner(mozilla::Side aSide, bool aIsSecond,
1138 bool aIsParallel) {
1139 return HalfCorner(((aSide + aIsSecond) * 2 + (aSide + !aIsParallel) % 2) % 8);
1142 } // namespace mozilla
1144 #endif /* MOZILLA_GFX_TYPES_H_ */