• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
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 
8 #ifndef GrSwizzle_DEFINED
9 #define GrSwizzle_DEFINED
10 
11 #include "GrColor.h"
12 #include "SkRandom.h"
13 
14 /** Represents a rgba swizzle. It can be converted either into a string or a eight bit int.
15     Currently there is no way to specify an arbitrary swizzle, just some static swizzles and an
16     assignment operator. That could be relaxed. */
17 class GrSwizzle {
18 public:
GrSwizzle()19     GrSwizzle() { *this = RGBA(); }
20 
GrSwizzle(const GrSwizzle & that)21     GrSwizzle(const GrSwizzle& that) { *this = that; }
22 
23     GrSwizzle& operator=(const GrSwizzle& that) {
24         memcpy(this, &that, sizeof(GrSwizzle));
25         return *this;
26     }
27 
28     /** Recreates a GrSwizzle from the output of asKey() */
setFromKey(uint8_t key)29     void setFromKey(uint8_t key) {
30         fKey = key;
31         for (int i = 0; i < 4; ++i) {
32             fSwiz[i] = IdxToChar(key & 3);
33             key >>= 2;
34         }
35         SkASSERT(fSwiz[4] == 0);
36     }
37 
38     bool operator==(const GrSwizzle& that) const { return this->asUInt() == that.asUInt(); }
39 
40     bool operator!=(const GrSwizzle& that) const { return !(*this == that); }
41 
42     /** Compact representation of the swizzle suitable for a key. */
asKey()43     uint8_t asKey() const { return fKey; }
44 
45     /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */
c_str()46     const char* c_str() const { return fSwiz; }
47 
48     /** Applies this swizzle to the input color and returns the swizzled color. */
applyTo(GrColor color)49     GrColor applyTo(GrColor color) const {
50         int idx;
51         uint32_t key = fKey;
52         // Index of the input color that should be mapped to output r.
53         idx = (key & 3);
54         uint32_t outR = (color >> idx * 8)  & 0xFF;
55         key >>= 2;
56         idx = (key & 3);
57         uint32_t outG = (color >> idx * 8)  & 0xFF;
58         key >>= 2;
59         idx = (key & 3);
60         uint32_t outB = (color >> idx * 8)  & 0xFF;
61         key >>= 2;
62         idx = (key & 3);
63         uint32_t outA = (color >> idx * 8)  & 0xFF;
64         return GrColorPackRGBA(outR, outG, outB, outA);
65     }
66 
RGBA()67     static const GrSwizzle& RGBA() {
68         static GrSwizzle gRGBA("rgba");
69         return gRGBA;
70     }
71 
AAAA()72     static const GrSwizzle& AAAA() {
73         static GrSwizzle gAAAA("aaaa");
74         return gAAAA;
75     }
76 
RRRR()77     static const GrSwizzle& RRRR() {
78         static GrSwizzle gRRRR("rrrr");
79         return gRRRR;
80     }
81 
BGRA()82     static const GrSwizzle& BGRA() {
83         static GrSwizzle gBGRA("bgra");
84         return gBGRA;
85     }
86 
CreateRandom(SkRandom * random)87     static const GrSwizzle& CreateRandom(SkRandom* random) {
88         switch (random->nextU() % 4) {
89             case 0:
90                 return RGBA();
91             case 1:
92                 return BGRA();
93             case 2:
94                 return RRRR();
95             case 3:
96                 return AAAA();
97             default:
98                 SkFAIL("Mod is broken?!?");
99                 return RGBA();
100         }
101     }
102 
103 private:
104     char fSwiz[5];
105     uint8_t fKey;
106 
CharToIdx(char c)107     static int CharToIdx(char c) {
108         switch (c) {
109             case 'r':
110                 return (GrColor_SHIFT_R / 8);
111             case 'g':
112                 return (GrColor_SHIFT_G / 8);
113             case 'b':
114                 return (GrColor_SHIFT_B / 8);
115             case 'a':
116                 return (GrColor_SHIFT_A / 8);
117             default:
118                 SkFAIL("Invalid swizzle char");
119                 return 0;
120         }
121     }
122 
IToC(int idx)123     static /* constexpr */ char IToC(int idx) {
124         return (8*idx) == GrColor_SHIFT_R ? 'r' :
125                (8*idx) == GrColor_SHIFT_G ? 'g' :
126                (8*idx) == GrColor_SHIFT_B ? 'b' : 'a';
127     }
128 
IdxToChar(int c)129     static char IdxToChar(int c) {
130         // Hopefully this array gets computed at compile time.
131         static const char gStr[4] = { IToC(0), IToC(1), IToC(2), IToC(3) };
132         return gStr[c];
133     }
134 
GrSwizzle(const char * str)135     explicit GrSwizzle(const char* str) {
136         SkASSERT(strlen(str) == 4);
137         fSwiz[0] = str[0];
138         fSwiz[1] = str[1];
139         fSwiz[2] = str[2];
140         fSwiz[3] = str[3];
141         fSwiz[4] = 0;
142         fKey = SkToU8(CharToIdx(fSwiz[0]) | (CharToIdx(fSwiz[1]) << 2) |
143                       (CharToIdx(fSwiz[2]) << 4) | (CharToIdx(fSwiz[3]) << 6));
144     }
145 
asUIntPtr()146     uint32_t* asUIntPtr() { return SkTCast<uint32_t*>(fSwiz); }
asUInt()147     uint32_t asUInt() const { return *SkTCast<const uint32_t*>(fSwiz); }
148 
149     GR_STATIC_ASSERT(sizeof(char[4]) == sizeof(uint32_t));
150 };
151 
152 #endif
153