1
2 /*
3 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10
11 #ifndef GrColor_DEFINED
12 #define GrColor_DEFINED
13
14 #include "SkColor.h"
15 #include "SkColorData.h"
16 #include "SkColorPriv.h"
17 #include "SkHalf.h"
18
19 /**
20 * GrColor is 4 bytes for R, G, B, A, in a specific order defined below. Whether the color is
21 * premultiplied or not depends on the context in which it is being used.
22 */
23 typedef uint32_t GrColor;
24
25 // shift amount to assign a component to a GrColor int
26 // These shift values are chosen for compatibility with GL attrib arrays
27 // ES doesn't allow BGRA vertex attrib order so if they were not in this order
28 // we'd have to swizzle in shaders.
29 #ifdef SK_CPU_BENDIAN
30 #define GrColor_SHIFT_R 24
31 #define GrColor_SHIFT_G 16
32 #define GrColor_SHIFT_B 8
33 #define GrColor_SHIFT_A 0
34 #else
35 #define GrColor_SHIFT_R 0
36 #define GrColor_SHIFT_G 8
37 #define GrColor_SHIFT_B 16
38 #define GrColor_SHIFT_A 24
39 #endif
40
41 /**
42 * Pack 4 components (RGBA) into a GrColor int
43 */
GrColorPackRGBA(unsigned r,unsigned g,unsigned b,unsigned a)44 static inline GrColor GrColorPackRGBA(unsigned r, unsigned g, unsigned b, unsigned a) {
45 SkASSERT((uint8_t)r == r);
46 SkASSERT((uint8_t)g == g);
47 SkASSERT((uint8_t)b == b);
48 SkASSERT((uint8_t)a == a);
49 return (r << GrColor_SHIFT_R) |
50 (g << GrColor_SHIFT_G) |
51 (b << GrColor_SHIFT_B) |
52 (a << GrColor_SHIFT_A);
53 }
54
55 // extract a component (byte) from a GrColor int
56
57 #define GrColorUnpackR(color) (((color) >> GrColor_SHIFT_R) & 0xFF)
58 #define GrColorUnpackG(color) (((color) >> GrColor_SHIFT_G) & 0xFF)
59 #define GrColorUnpackB(color) (((color) >> GrColor_SHIFT_B) & 0xFF)
60 #define GrColorUnpackA(color) (((color) >> GrColor_SHIFT_A) & 0xFF)
61
62 /**
63 * Since premultiplied means that alpha >= color, we construct a color with
64 * each component==255 and alpha == 0 to be "illegal"
65 */
66 #define GrColor_ILLEGAL (~(0xFF << GrColor_SHIFT_A))
67
68 /** Normalizes and coverts an uint8_t to a float. [0, 255] -> [0.0, 1.0] */
GrNormalizeByteToFloat(uint8_t value)69 static inline float GrNormalizeByteToFloat(uint8_t value) {
70 static const float ONE_OVER_255 = 1.f / 255.f;
71 return value * ONE_OVER_255;
72 }
73
74 /** Returns true if all channels are in [0, 1]. Used to pick vertex attribute types. */
SkPMColor4fFitsInBytes(const SkPMColor4f & color)75 static inline bool SkPMColor4fFitsInBytes(const SkPMColor4f& color) {
76 SkASSERT(color.fA >= 0.0f && color.fA <= 1.0f);
77 return color.fR >= 0.0f && color.fR <= 1.0f &&
78 color.fG >= 0.0f && color.fG <= 1.0f &&
79 color.fB >= 0.0f && color.fB <= 1.0f;
80 }
81
SkPMColor4f_toFP16(const SkPMColor4f & color)82 static inline uint64_t SkPMColor4f_toFP16(const SkPMColor4f& color) {
83 uint64_t halfColor;
84 SkFloatToHalf_finite_ftz(Sk4f::Load(color.vec())).store(&halfColor);
85 return halfColor;
86 }
87
88 /**
89 * GrVertexColor is a helper for writing colors to a vertex attribute. It stores either GrColor
90 * or four half-float channels, depending on the wideColor parameter. GrVertexWriter will write
91 * the correct amount of data. Note that the GP needs to have been constructed with the correct
92 * attribute type for colors, to match the usage here.
93 */
94 class GrVertexColor {
95 public:
GrVertexColor(const SkPMColor4f & color,bool wideColor)96 explicit GrVertexColor(const SkPMColor4f& color, bool wideColor)
97 : fWideColor(wideColor) {
98 if (wideColor) {
99 SkFloatToHalf_finite_ftz(Sk4f::Load(color.vec())).store(&fColor);
100 } else {
101 fColor[0] = color.toBytes_RGBA();
102 }
103 }
104
size()105 size_t size() const { return fWideColor ? 8 : 4; }
106
107 private:
108 friend struct GrVertexWriter;
109
110 uint32_t fColor[2];
111 bool fWideColor;
112 };
113
114 #endif
115