SkColorPriv.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkColorPriv_DEFINED
  8. #define SkColorPriv_DEFINED
  9. #include "include/core/SkColor.h"
  10. #include "include/core/SkMath.h"
  11. #include "include/private/SkTo.h"
  12. /** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a
  13. byte into a scale value, so that we can say scale * value >> 8 instead of
  14. alpha * value / 255.
  15. In debugging, asserts that alpha is 0..255
  16. */
  17. static inline unsigned SkAlpha255To256(U8CPU alpha) {
  18. SkASSERT(SkToU8(alpha) == alpha);
  19. // this one assues that blending on top of an opaque dst keeps it that way
  20. // even though it is less accurate than a+(a>>7) for non-opaque dsts
  21. return alpha + 1;
  22. }
  23. /** Multiplify value by 0..256, and shift the result down 8
  24. (i.e. return (value * alpha256) >> 8)
  25. */
  26. #define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8)
  27. static inline U8CPU SkUnitScalarClampToByte(SkScalar x) {
  28. return static_cast<U8CPU>(SkScalarPin(x, 0, 1) * 255 + 0.5);
  29. }
  30. #define SK_A32_BITS 8
  31. #define SK_R32_BITS 8
  32. #define SK_G32_BITS 8
  33. #define SK_B32_BITS 8
  34. #define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
  35. #define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
  36. #define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
  37. #define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
  38. /*
  39. * Skia's 32bit backend only supports 1 swizzle order at a time (compile-time).
  40. * This is specified by SK_R32_SHIFT=0 or SK_R32_SHIFT=16.
  41. *
  42. * For easier compatibility with Skia's GPU backend, we further restrict these
  43. * to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does
  44. * not directly correspond to the same shift-order, since we have to take endianess
  45. * into account.
  46. *
  47. * Here we enforce this constraint.
  48. */
  49. #define SK_RGBA_R32_SHIFT 0
  50. #define SK_RGBA_G32_SHIFT 8
  51. #define SK_RGBA_B32_SHIFT 16
  52. #define SK_RGBA_A32_SHIFT 24
  53. #define SK_BGRA_B32_SHIFT 0
  54. #define SK_BGRA_G32_SHIFT 8
  55. #define SK_BGRA_R32_SHIFT 16
  56. #define SK_BGRA_A32_SHIFT 24
  57. #if defined(SK_PMCOLOR_IS_RGBA) || defined(SK_PMCOLOR_IS_BGRA)
  58. #error "Configure PMCOLOR by setting SK_R32_SHIFT."
  59. #endif
  60. // Deduce which SK_PMCOLOR_IS_ to define from the _SHIFT defines
  61. #if (SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \
  62. SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \
  63. SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \
  64. SK_B32_SHIFT == SK_RGBA_B32_SHIFT)
  65. #define SK_PMCOLOR_IS_RGBA
  66. #elif (SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \
  67. SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \
  68. SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \
  69. SK_B32_SHIFT == SK_BGRA_B32_SHIFT)
  70. #define SK_PMCOLOR_IS_BGRA
  71. #else
  72. #error "need 32bit packing to be either RGBA or BGRA"
  73. #endif
  74. #define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
  75. #define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
  76. #define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
  77. #define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
  78. #define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK)
  79. #define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK)
  80. #define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK)
  81. #define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK)
  82. /**
  83. * Pack the components into a SkPMColor, checking (in the debug version) that
  84. * the components are 0..255, and are already premultiplied (i.e. alpha >= color)
  85. */
  86. static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
  87. SkA32Assert(a);
  88. SkASSERT(r <= a);
  89. SkASSERT(g <= a);
  90. SkASSERT(b <= a);
  91. return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
  92. (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
  93. }
  94. /**
  95. * Same as SkPackARGB32, but this version guarantees to not check that the
  96. * values are premultiplied in the debug version.
  97. */
  98. static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
  99. return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
  100. (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
  101. }
  102. static inline
  103. SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
  104. SkA32Assert(a);
  105. SkR32Assert(r);
  106. SkG32Assert(g);
  107. SkB32Assert(b);
  108. if (a != 255) {
  109. r = SkMulDiv255Round(r, a);
  110. g = SkMulDiv255Round(g, a);
  111. b = SkMulDiv255Round(b, a);
  112. }
  113. return SkPackARGB32(a, r, g, b);
  114. }
  115. // When Android is compiled optimizing for size, SkAlphaMulQ doesn't get
  116. // inlined; forcing inlining significantly improves performance.
  117. static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
  118. uint32_t mask = 0xFF00FF;
  119. uint32_t rb = ((c & mask) * scale) >> 8;
  120. uint32_t ag = ((c >> 8) & mask) * scale;
  121. return (rb & mask) | (ag & ~mask);
  122. }
  123. static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
  124. return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
  125. }
  126. #endif