blob: 109c3a63d8e529af09eb0953ae851846d0a51dbb [file] [log] [blame]
bsalomoncdee0092016-01-08 13:20:12 -08001/*
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
bsalomon7f9b2e42016-01-12 13:29:26 -080011#include "GrColor.h"
Brian Osmane3f543c2018-11-02 12:52:10 -040012#include "SkColorData.h"
bsalomoncdee0092016-01-08 13:20:12 -080013
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. */
17class GrSwizzle {
18public:
Brian Salomon21511652018-10-17 08:30:51 -040019 constexpr GrSwizzle() : GrSwizzle("rgba") {}
bsalomoncdee0092016-01-08 13:20:12 -080020
Brian Salomon21511652018-10-17 08:30:51 -040021 constexpr GrSwizzle(const GrSwizzle& that)
22 : fSwiz{that.fSwiz[0], that.fSwiz[1], that.fSwiz[2], that.fSwiz[3], '\0'}
23 , fKey(that.fKey) {}
bsalomon7f9b2e42016-01-12 13:29:26 -080024
Brian Salomon21511652018-10-17 08:30:51 -040025 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;
bsalomoncdee0092016-01-08 13:20:12 -080032 return *this;
33 }
34
bsalomon7f9b2e42016-01-12 13:29:26 -080035 /** Recreates a GrSwizzle from the output of asKey() */
Brian Salomon21511652018-10-17 08:30:51 -040036 constexpr void setFromKey(uint8_t key) {
bsalomon7f9b2e42016-01-12 13:29:26 -080037 fKey = key;
38 for (int i = 0; i < 4; ++i) {
Brian Salomon1aaccc72016-11-18 15:08:06 -050039 fSwiz[i] = IToC(key & 3);
bsalomon7f9b2e42016-01-12 13:29:26 -080040 key >>= 2;
41 }
42 SkASSERT(fSwiz[4] == 0);
43 }
44
Brian Salomon21511652018-10-17 08:30:51 -040045 constexpr bool operator==(const GrSwizzle& that) const { return fKey == that.fKey; }
46 constexpr bool operator!=(const GrSwizzle& that) const { return !(*this == that); }
bsalomoncdee0092016-01-08 13:20:12 -080047
48 /** Compact representation of the swizzle suitable for a key. */
Brian Salomon21511652018-10-17 08:30:51 -040049 constexpr uint8_t asKey() const { return fKey; }
bsalomoncdee0092016-01-08 13:20:12 -080050
51 /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */
52 const char* c_str() const { return fSwiz; }
53
Brian Salomondc829942018-10-23 16:07:24 -040054 char operator[](int i) const {
55 SkASSERT(i >= 0 && i < 4);
56 return fSwiz[i];
57 }
58
bsalomon7f9b2e42016-01-12 13:29:26 -080059 /** Applies this swizzle to the input color and returns the swizzled color. */
Brian Osman1d5b5982018-10-01 13:41:39 -040060 SkPMColor4f applyTo(const SkPMColor4f& color) const {
Brian Osmance425512017-03-22 14:37:50 -040061 int idx;
62 uint32_t key = fKey;
63 // Index of the input color that should be mapped to output r.
64 idx = (key & 3);
Brian Osman1d5b5982018-10-01 13:41:39 -040065 float outR = color[idx];
Brian Osmance425512017-03-22 14:37:50 -040066 key >>= 2;
67 idx = (key & 3);
Brian Osman1d5b5982018-10-01 13:41:39 -040068 float outG = color[idx];
Brian Osmance425512017-03-22 14:37:50 -040069 key >>= 2;
70 idx = (key & 3);
Brian Osman1d5b5982018-10-01 13:41:39 -040071 float outB = color[idx];
Brian Osmance425512017-03-22 14:37:50 -040072 key >>= 2;
73 idx = (key & 3);
Brian Osman1d5b5982018-10-01 13:41:39 -040074 float outA = color[idx];
75 return { outR, outG, outB, outA };
Brian Osmance425512017-03-22 14:37:50 -040076 }
77
Brian Salomon21511652018-10-17 08:30:51 -040078 static constexpr GrSwizzle RGBA() { return GrSwizzle("rgba"); }
79 static constexpr GrSwizzle AAAA() { return GrSwizzle("aaaa"); }
80 static constexpr GrSwizzle RRRR() { return GrSwizzle("rrrr"); }
81 static constexpr GrSwizzle RRRA() { return GrSwizzle("rrra"); }
82 static constexpr GrSwizzle BGRA() { return GrSwizzle("bgra"); }
Jim Van Verth69e57852018-12-05 13:38:59 -050083 static constexpr GrSwizzle RGRG() { return GrSwizzle("rgrg"); }
bsalomoncdee0092016-01-08 13:20:12 -080084
Brian Salomon21511652018-10-17 08:30:51 -040085private:
86 char fSwiz[5];
87 uint8_t fKey;
88
89 static constexpr int CToI(char c) {
90 switch (c) {
91 case 'r': return (GrColor_SHIFT_R / 8);
92 case 'g': return (GrColor_SHIFT_G / 8);
93 case 'b': return (GrColor_SHIFT_B / 8);
94 case 'a': return (GrColor_SHIFT_A / 8);
95 default: return -1;
bsalomon6c9cd552016-01-22 07:17:34 -080096 }
97 }
Brian Salomon21511652018-10-17 08:30:51 -040098
99 static constexpr char IToC(int idx) {
100 switch (8 * idx) {
101 case GrColor_SHIFT_R : return 'r';
102 case GrColor_SHIFT_G : return 'g';
103 case GrColor_SHIFT_B : return 'b';
104 case GrColor_SHIFT_A : return 'a';
Brian Salomondc829942018-10-23 16:07:24 -0400105 default: return -1;
Brian Salomon21511652018-10-17 08:30:51 -0400106 }
107 }
108
109 constexpr GrSwizzle(const char c[4])
110 : fSwiz{c[0], c[1], c[2], c[3], '\0'}
111 , fKey((CToI(c[0]) << 0) | (CToI(c[1]) << 2) | (CToI(c[2]) << 4) | (CToI(c[3]) << 6)) {}
bsalomoncdee0092016-01-08 13:20:12 -0800112};
113
114#endif