Flutter Engine
The Flutter Engine
Swizzle.h
Go to the documentation of this file.
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 skgpu_Swizzle_DEFINED
9#define skgpu_Swizzle_DEFINED
10
15
16#include <array>
17#include <cstddef>
18#include <cstdint>
19#include <type_traits>
20
22enum SkAlphaType : int;
23
24namespace skgpu {
25
26/** Represents a rgba swizzle. It can be converted either into a string or a eight bit int. */
27class Swizzle {
28public:
29 // Equivalent to "rgba", but Clang doesn't always manage to inline this
30 // if we're too deep in the inlining already.
31 constexpr Swizzle() : Swizzle(0x3210) {}
32 explicit constexpr Swizzle(const char c[4]);
33
34 constexpr Swizzle(const Swizzle&) = default;
35 constexpr Swizzle& operator=(const Swizzle& that) = default;
36
37 static constexpr Swizzle Concat(const Swizzle& a, const Swizzle& b);
38
39 constexpr bool operator==(const Swizzle& that) const { return fKey == that.fKey; }
40 constexpr bool operator!=(const Swizzle& that) const { return !(*this == that); }
41
42 /** Compact representation of the swizzle suitable for a key. */
43 constexpr uint16_t asKey() const { return fKey; }
44
45 /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a', '0', and '1'. */
46 SkString asString() const;
47
48 constexpr char operator[](int i) const { return IToC(this->channelIndex(i)); }
49
50 // Returns a new swizzle that moves the swizzle component in index i to index 0 (e.g. "R") and
51 // sets all other channels to 0. For a swizzle `s`, this is constructing "s[i]000".
52 constexpr Swizzle selectChannelInR(int i) const;
53
54 /** Applies this swizzle to the input color and returns the swizzled color. */
55 constexpr std::array<float, 4> applyTo(std::array<float, 4> color) const;
56
57 /** Convenience version for SkRGBA colors. */
58 template <SkAlphaType AlphaType>
60 std::array<float, 4> result = this->applyTo(color.array());
61 return {result[0], result[1], result[2], result[3]};
62 }
63
64 void apply(SkRasterPipeline*) const;
65
66 static constexpr Swizzle RGBA() { return Swizzle("rgba"); }
67 static constexpr Swizzle BGRA() { return Swizzle("bgra"); }
68 static constexpr Swizzle RRRA() { return Swizzle("rrra"); }
69 static constexpr Swizzle RGB1() { return Swizzle("rgb1"); }
70
71 using sk_is_trivially_relocatable = std::true_type;
72
73private:
74 friend class SwizzleCtorAccessor;
75
76 explicit constexpr Swizzle(uint16_t key) : fKey(key) {}
77
78 constexpr int channelIndex(int i) const {
79 SkASSERT(i >= 0 && i < 4);
80 return (fKey >> (4*i)) & 0xfU;
81 }
82
83 static constexpr float ComponentIndexToFloat(std::array<float, 4>, size_t idx);
84 static constexpr int CToI(char c);
85 static constexpr char IToC(int idx);
86
87 uint16_t fKey;
88
89 static_assert(::sk_is_trivially_relocatable<decltype(fKey)>::value);
90};
91
92constexpr Swizzle::Swizzle(const char c[4])
93 : fKey(static_cast<uint16_t>((CToI(c[0]) << 0) | (CToI(c[1]) << 4) | (CToI(c[2]) << 8) |
94 (CToI(c[3]) << 12))) {}
95
96constexpr Swizzle Swizzle::selectChannelInR(int i) const {
97 return Swizzle(static_cast<uint16_t>((this->channelIndex(i) << 0) | (CToI('0') << 4) |
98 (CToI('0') << 8) | (CToI('0') << 12)));
99}
100
101constexpr std::array<float, 4> Swizzle::applyTo(std::array<float, 4> color) const {
102 uint32_t key = fKey;
103 // Index of the input color that should be mapped to output r.
104 size_t idx = (key & 15);
105 float outR = ComponentIndexToFloat(color, idx);
106 key >>= 4;
107 idx = (key & 15);
108 float outG = ComponentIndexToFloat(color, idx);
109 key >>= 4;
110 idx = (key & 15);
111 float outB = ComponentIndexToFloat(color, idx);
112 key >>= 4;
113 idx = (key & 15);
114 float outA = ComponentIndexToFloat(color, idx);
115 return { outR, outG, outB, outA };
116}
117
118constexpr float Swizzle::ComponentIndexToFloat(std::array<float, 4> color, size_t idx) {
119 if (idx <= 3) {
120 return color[idx];
121 }
122 if (idx == static_cast<size_t>(CToI('1'))) {
123 return 1.0f;
124 }
125 if (idx == static_cast<size_t>(CToI('0'))) {
126 return 0.0f;
127 }
129}
130
131constexpr int Swizzle::CToI(char c) {
132 switch (c) {
133 // r...a must map to 0...3 because other methods use them as indices into fSwiz.
134 case 'r': return 0;
135 case 'g': return 1;
136 case 'b': return 2;
137 case 'a': return 3;
138 case '0': return 4;
139 case '1': return 5;
140 default: SkUNREACHABLE;
141 }
142}
143
144constexpr char Swizzle::IToC(int idx) {
145 switch (idx) {
146 case CToI('r'): return 'r';
147 case CToI('g'): return 'g';
148 case CToI('b'): return 'b';
149 case CToI('a'): return 'a';
150 case CToI('0'): return '0';
151 case CToI('1'): return '1';
152 default: SkUNREACHABLE;
153 }
154}
155
156constexpr Swizzle Swizzle::Concat(const Swizzle& a, const Swizzle& b) {
157 uint16_t key = 0;
158 for (unsigned i = 0; i < 4; ++i) {
159 int idx = (b.fKey >> (4U * i)) & 0xfU;
160 if (idx != CToI('0') && idx != CToI('1')) {
161 SkASSERT(idx >= 0 && idx < 4);
162 // Get the index value stored in a at location idx.
163 idx = ((a.fKey >> (4 * idx)) & 0xfU);
164 }
165 key |= (idx << (4U * i));
166 }
167 return Swizzle(key);
168}
169
170} // namespace skgpu
171#endif
SkAlphaType
Definition: SkAlphaType.h:26
#define SkUNREACHABLE
Definition: SkAssert.h:135
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr std::array< float, 4 > applyTo(std::array< float, 4 > color) const
Definition: Swizzle.h:101
constexpr Swizzle()
Definition: Swizzle.h:31
constexpr Swizzle(const Swizzle &)=default
static constexpr Swizzle RRRA()
Definition: Swizzle.h:68
constexpr uint16_t asKey() const
Definition: Swizzle.h:43
constexpr SkRGBA4f< AlphaType > applyTo(SkRGBA4f< AlphaType > color) const
Definition: Swizzle.h:59
constexpr bool operator==(const Swizzle &that) const
Definition: Swizzle.h:39
constexpr Swizzle & operator=(const Swizzle &that)=default
constexpr Swizzle selectChannelInR(int i) const
Definition: Swizzle.h:96
constexpr char operator[](int i) const
Definition: Swizzle.h:48
static constexpr Swizzle Concat(const Swizzle &a, const Swizzle &b)
Definition: Swizzle.h:156
SkString asString() const
Definition: Swizzle.cpp:46
std::true_type sk_is_trivially_relocatable
Definition: Swizzle.h:71
static constexpr Swizzle BGRA()
Definition: Swizzle.h:67
static constexpr Swizzle RGBA()
Definition: Swizzle.h:66
constexpr bool operator!=(const Swizzle &that) const
Definition: Swizzle.h:40
void apply(SkRasterPipeline *) const
Definition: Swizzle.cpp:17
static constexpr Swizzle RGB1()
Definition: Swizzle.h:69
DlColor color
static bool b
struct MyStruct a[10]
uint8_t value
GAsyncResult * result
Definition: GpuTools.h:21
std::array< float, 4 > array() const
Definition: SkColor.h:317