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