2 * Copyright 2016 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef skgpu_Swizzle_DEFINED
9 #define skgpu_Swizzle_DEFINED
11 #include "include/core/SkAlphaType.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkString.h"
15 class SkRasterPipeline;
19 /** Represents a rgba swizzle. It can be converted either into a string or a eight bit int. */
22 constexpr Swizzle() : Swizzle("rgba") {}
23 explicit constexpr Swizzle(const char c[4]);
25 constexpr Swizzle(const Swizzle&);
26 constexpr Swizzle& operator=(const Swizzle& that);
28 static constexpr Swizzle Concat(const Swizzle& a, const Swizzle& b);
30 constexpr bool operator==(const Swizzle& that) const { return fKey == that.fKey; }
31 constexpr bool operator!=(const Swizzle& that) const { return !(*this == that); }
33 /** Compact representation of the swizzle suitable for a key. */
34 constexpr uint16_t asKey() const { return fKey; }
36 /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a', '0', and '1'. */
37 SkString asString() const;
39 constexpr char operator[](int i) const {
40 SkASSERT(i >= 0 && i < 4);
41 int idx = (fKey >> (4U * i)) & 0xfU;
45 /** Applies this swizzle to the input color and returns the swizzled color. */
46 constexpr std::array<float, 4> applyTo(std::array<float, 4> color) const;
48 /** Convenience version for SkRGBA colors. */
49 template <SkAlphaType AlphaType>
50 constexpr SkRGBA4f<AlphaType> applyTo(SkRGBA4f<AlphaType> color) const {
51 std::array<float, 4> result = this->applyTo(color.array());
52 return {result[0], result[1], result[2], result[3]};
55 void apply(SkRasterPipeline*) const;
57 static constexpr Swizzle RGBA() { return Swizzle("rgba"); }
58 static constexpr Swizzle BGRA() { return Swizzle("bgra"); }
59 static constexpr Swizzle RRRA() { return Swizzle("rrra"); }
60 static constexpr Swizzle RGB1() { return Swizzle("rgb1"); }
63 explicit constexpr Swizzle(uint16_t key) : fKey(key) {}
65 static constexpr float ComponentIndexToFloat(std::array<float, 4>, int idx);
66 static constexpr int CToI(char c);
67 static constexpr char IToC(int idx);
72 constexpr Swizzle::Swizzle(const char c[4])
73 : fKey((CToI(c[0]) << 0) | (CToI(c[1]) << 4) | (CToI(c[2]) << 8) | (CToI(c[3]) << 12)) {}
75 constexpr Swizzle::Swizzle(const Swizzle& that)
78 constexpr Swizzle& Swizzle::operator=(const Swizzle& that) {
83 constexpr std::array<float, 4> Swizzle::applyTo(std::array<float, 4> color) const {
85 // Index of the input color that should be mapped to output r.
87 float outR = ComponentIndexToFloat(color, idx);
90 float outG = ComponentIndexToFloat(color, idx);
93 float outB = ComponentIndexToFloat(color, idx);
96 float outA = ComponentIndexToFloat(color, idx);
97 return { outR, outG, outB, outA };
100 constexpr float Swizzle::ComponentIndexToFloat(std::array<float, 4> color, int idx) {
104 if (idx == CToI('1')) {
107 if (idx == CToI('0')) {
113 constexpr int Swizzle::CToI(char c) {
115 // r...a must map to 0...3 because other methods use them as indices into fSwiz.
122 default: SkUNREACHABLE;
126 constexpr char Swizzle::IToC(int idx) {
128 case CToI('r'): return 'r';
129 case CToI('g'): return 'g';
130 case CToI('b'): return 'b';
131 case CToI('a'): return 'a';
132 case CToI('0'): return '0';
133 case CToI('1'): return '1';
134 default: SkUNREACHABLE;
138 constexpr Swizzle Swizzle::Concat(const Swizzle& a, const Swizzle& b) {
140 for (int i = 0; i < 4; ++i) {
141 int idx = (b.fKey >> (4U * i)) & 0xfU;
142 if (idx != CToI('0') && idx != CToI('1')) {
143 SkASSERT(idx >= 0 && idx < 4);
144 // Get the index value stored in a at location idx.
145 idx = ((a.fKey >> (4U * idx)) & 0xfU);
147 key |= (idx << (4U * i));