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 "GrTypes.h"
15
16/**
17 * GrColor is 4 bytes for R, G, B, A, in a specific order defined below. The components are stored
18 * premultiplied.
19 */
20typedef uint32_t GrColor;
21
22// shift amount to assign a component to a GrColor int
23// These shift values are chosen for compatibility with GL attrib arrays
24// ES doesn't allow BGRA vertex attrib order so if they were not in this order
25// we'd have to swizzle in shaders.
26#ifdef SK_CPU_BENDIAN
27    #define GrColor_SHIFT_R     24
28    #define GrColor_SHIFT_G     16
29    #define GrColor_SHIFT_B     8
30    #define GrColor_SHIFT_A     0
31#else
32    #define GrColor_SHIFT_R     0
33    #define GrColor_SHIFT_G     8
34    #define GrColor_SHIFT_B     16
35    #define GrColor_SHIFT_A     24
36#endif
37
38/**
39 *  Pack 4 components (RGBA) into a GrColor int
40 */
41static inline GrColor GrColorPackRGBA(unsigned r, unsigned g,
42                                      unsigned b, unsigned a) {
43    SkASSERT((uint8_t)r == r);
44    SkASSERT((uint8_t)g == g);
45    SkASSERT((uint8_t)b == b);
46    SkASSERT((uint8_t)a == a);
47    return  (r << GrColor_SHIFT_R) |
48            (g << GrColor_SHIFT_G) |
49            (b << GrColor_SHIFT_B) |
50            (a << GrColor_SHIFT_A);
51}
52
53// extract a component (byte) from a GrColor int
54
55#define GrColorUnpackR(color)   (((color) >> GrColor_SHIFT_R) & 0xFF)
56#define GrColorUnpackG(color)   (((color) >> GrColor_SHIFT_G) & 0xFF)
57#define GrColorUnpackB(color)   (((color) >> GrColor_SHIFT_B) & 0xFF)
58#define GrColorUnpackA(color)   (((color) >> GrColor_SHIFT_A) & 0xFF)
59
60/**
61 *  Since premultiplied means that alpha >= color, we construct a color with
62 *  each component==255 and alpha == 0 to be "illegal"
63 */
64#define GrColor_ILLEGAL     (~(0xFF << GrColor_SHIFT_A))
65
66/**
67 * Assert in debug builds that a GrColor is premultiplied.
68 */
69static inline void GrColorIsPMAssert(GrColor c) {
70#ifdef SK_DEBUG
71    unsigned a = GrColorUnpackA(c);
72    unsigned r = GrColorUnpackR(c);
73    unsigned g = GrColorUnpackG(c);
74    unsigned b = GrColorUnpackB(c);
75
76    SkASSERT(r <= a);
77    SkASSERT(g <= a);
78    SkASSERT(b <= a);
79#endif
80}
81
82/** Converts a GrColor to an rgba array of GrGLfloat */
83static inline void GrColorToRGBAFloat(GrColor color, float rgba[4]) {
84    static const float ONE_OVER_255 = 1.f / 255.f;
85    rgba[0] = GrColorUnpackR(color) * ONE_OVER_255;
86    rgba[1] = GrColorUnpackG(color) * ONE_OVER_255;
87    rgba[2] = GrColorUnpackB(color) * ONE_OVER_255;
88    rgba[3] = GrColorUnpackA(color) * ONE_OVER_255;
89}
90
91/**
92 * Flags used for bitfields of color components. They are defined so that the bit order reflects the
93 * GrColor shift order.
94 */
95enum GrColorComponentFlags {
96    kR_GrColorComponentFlag = 1 << (GrColor_SHIFT_R / 8),
97    kG_GrColorComponentFlag = 1 << (GrColor_SHIFT_G / 8),
98    kB_GrColorComponentFlag = 1 << (GrColor_SHIFT_B / 8),
99    kA_GrColorComponentFlag = 1 << (GrColor_SHIFT_A / 8),
100
101    kRGB_GrColorComponentFlags = (kR_GrColorComponentFlag | kG_GrColorComponentFlag |
102                                  kB_GrColorComponentFlag),
103
104    kRGBA_GrColorComponentFlags = (kR_GrColorComponentFlag | kG_GrColorComponentFlag |
105                                   kB_GrColorComponentFlag | kA_GrColorComponentFlag)
106};
107
108static inline char GrColorComponentFlagToChar(GrColorComponentFlags component) {
109    SkASSERT(SkIsPow2(component));
110    switch (component) {
111        case kR_GrColorComponentFlag:
112            return 'r';
113        case kG_GrColorComponentFlag:
114            return 'g';
115        case kB_GrColorComponentFlag:
116            return 'b';
117        case kA_GrColorComponentFlag:
118            return 'a';
119        default:
120            SkFAIL("Invalid color component flag.");
121            return '\0';
122    }
123}
124
125static inline uint32_t GrPixelConfigComponentMask(GrPixelConfig config) {
126    SkASSERT(config >= 0 && config < kGrPixelConfigCnt);
127    static const uint32_t kFlags[] = {
128        0,                              // kUnknown_GrPixelConfig
129        kA_GrColorComponentFlag,        // kAlpha_8_GrPixelConfig
130        kRGBA_GrColorComponentFlags,    // kIndex_8_GrPixelConfig
131        kRGB_GrColorComponentFlags,     // kRGB_565_GrPixelConfig
132        kRGBA_GrColorComponentFlags,    // kRGBA_4444_GrPixelConfig
133        kRGBA_GrColorComponentFlags,    // kRGBA_8888_GrPixelConfig
134        kRGBA_GrColorComponentFlags,    // kBGRA_8888_GrPixelConfig
135        kRGB_GrColorComponentFlags,     // kETC1_GrPixelConfig
136        kA_GrColorComponentFlag,        // kLATC_GrPixelConfig
137    };
138    return kFlags[config];
139
140    GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
141    GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
142    GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
143    GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
144    GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
145    GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
146    GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
147    GR_STATIC_ASSERT(7 == kETC1_GrPixelConfig);
148    GR_STATIC_ASSERT(8 == kLATC_GrPixelConfig);
149    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFlags) == kGrPixelConfigCnt);
150}
151
152#endif
153