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 private: 19 char fSwiz[5]; 20 uint8_t fKey; 21 CToI(char c)22 static constexpr int CToI(char c) { 23 return ('r' == c) ? (GrColor_SHIFT_R / 8) : 24 ('g' == c) ? (GrColor_SHIFT_G / 8) : 25 ('b' == c) ? (GrColor_SHIFT_B / 8) : 26 ('a' == c) ? (GrColor_SHIFT_A / 8) : -1; 27 } 28 IToC(int idx)29 static constexpr char IToC(int idx) { 30 return (8 * idx) == GrColor_SHIFT_R ? 'r' : 31 (8 * idx) == GrColor_SHIFT_G ? 'g' : 32 (8 * idx) == GrColor_SHIFT_B ? 'b' : 33 (8 * idx) == GrColor_SHIFT_A ? 'a' : 'x'; 34 } 35 GrSwizzle(const char c[4])36 constexpr GrSwizzle(const char c[4]) 37 : fSwiz{c[0], c[1], c[2], c[3], 0} 38 , fKey((CToI(c[0]) << 0) | (CToI(c[1]) << 2) | (CToI(c[2]) << 4) | (CToI(c[3]) << 6)) {} 39 40 GR_STATIC_ASSERT(sizeof(char[4]) == sizeof(uint32_t)); asUIntPtr()41 uint32_t* asUIntPtr() { return SkTCast<uint32_t*>(fSwiz); } asUInt()42 uint32_t asUInt() const { return *SkTCast<const uint32_t*>(fSwiz); } 43 44 public: GrSwizzle()45 GrSwizzle() { *this = RGBA(); } 46 GrSwizzle(const GrSwizzle & that)47 GrSwizzle(const GrSwizzle& that) { *this = that; } 48 49 GrSwizzle& operator=(const GrSwizzle& that) { 50 memcpy(this, &that, sizeof(GrSwizzle)); 51 return *this; 52 } 53 54 /** Recreates a GrSwizzle from the output of asKey() */ setFromKey(uint8_t key)55 void setFromKey(uint8_t key) { 56 fKey = key; 57 for (int i = 0; i < 4; ++i) { 58 fSwiz[i] = IToC(key & 3); 59 key >>= 2; 60 } 61 SkASSERT(fSwiz[4] == 0); 62 } 63 64 bool operator==(const GrSwizzle& that) const { return this->asUInt() == that.asUInt(); } 65 66 bool operator!=(const GrSwizzle& that) const { return !(*this == that); } 67 68 /** Compact representation of the swizzle suitable for a key. */ asKey()69 uint8_t asKey() const { return fKey; } 70 71 /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */ c_str()72 const char* c_str() const { return fSwiz; } 73 74 /** Applies this swizzle to the input color and returns the swizzled color. */ applyTo(GrColor color)75 GrColor applyTo(GrColor color) const { 76 int idx; 77 uint32_t key = fKey; 78 // Index of the input color that should be mapped to output r. 79 idx = (key & 3); 80 uint32_t outR = (color >> idx * 8) & 0xFF; 81 key >>= 2; 82 idx = (key & 3); 83 uint32_t outG = (color >> idx * 8) & 0xFF; 84 key >>= 2; 85 idx = (key & 3); 86 uint32_t outB = (color >> idx * 8) & 0xFF; 87 key >>= 2; 88 idx = (key & 3); 89 uint32_t outA = (color >> idx * 8) & 0xFF; 90 return GrColorPackRGBA(outR, outG, outB, outA); 91 } 92 93 /** Applies this swizzle to the input color and returns the swizzled color. */ applyTo(const GrColor4f & color)94 GrColor4f applyTo(const GrColor4f& color) const { 95 int idx; 96 uint32_t key = fKey; 97 // Index of the input color that should be mapped to output r. 98 idx = (key & 3); 99 float outR = color.fRGBA[idx]; 100 key >>= 2; 101 idx = (key & 3); 102 float outG = color.fRGBA[idx]; 103 key >>= 2; 104 idx = (key & 3); 105 float outB = color.fRGBA[idx]; 106 key >>= 2; 107 idx = (key & 3); 108 float outA = color.fRGBA[idx]; 109 return GrColor4f(outR, outG, outB, outA); 110 } 111 RGBA()112 static GrSwizzle RGBA() { return GrSwizzle("rgba"); } AAAA()113 static GrSwizzle AAAA() { return GrSwizzle("aaaa"); } RRRR()114 static GrSwizzle RRRR() { return GrSwizzle("rrrr"); } RRRA()115 static GrSwizzle RRRA() { return GrSwizzle("rrra"); } BGRA()116 static GrSwizzle BGRA() { return GrSwizzle("bgra"); } 117 CreateRandom(SkRandom * random)118 static GrSwizzle CreateRandom(SkRandom* random) { 119 switch (random->nextU() % 4) { 120 case 0: 121 return RGBA(); 122 case 1: 123 return BGRA(); 124 case 2: 125 return RRRR(); 126 case 3: 127 return AAAA(); 128 default: 129 SK_ABORT("Mod is broken?!?"); 130 return RGBA(); 131 } 132 } 133 }; 134 135 #endif 136