| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 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 |  | 
| bsalomon | 7f9b2e4 | 2016-01-12 13:29:26 -0800 | [diff] [blame] | 11 | #include "GrColor.h" | 
| Brian Osman | e3f543c | 2018-11-02 12:52:10 -0400 | [diff] [blame] | 12 | #include "SkColorData.h" | 
| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 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: | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 19 | constexpr GrSwizzle() : GrSwizzle("rgba") {} | 
| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 20 |  | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 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) {} | 
| bsalomon | 7f9b2e4 | 2016-01-12 13:29:26 -0800 | [diff] [blame] | 24 |  | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 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; | 
| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 32 | return *this; | 
|  | 33 | } | 
|  | 34 |  | 
| bsalomon | 7f9b2e4 | 2016-01-12 13:29:26 -0800 | [diff] [blame] | 35 | /** Recreates a GrSwizzle from the output of asKey() */ | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 36 | constexpr void setFromKey(uint16_t key) { | 
| bsalomon | 7f9b2e4 | 2016-01-12 13:29:26 -0800 | [diff] [blame] | 37 | fKey = key; | 
|  | 38 | for (int i = 0; i < 4; ++i) { | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 39 | fSwiz[i] = IToC(key & 15); | 
|  | 40 | key >>= 4; | 
| bsalomon | 7f9b2e4 | 2016-01-12 13:29:26 -0800 | [diff] [blame] | 41 | } | 
|  | 42 | SkASSERT(fSwiz[4] == 0); | 
|  | 43 | } | 
|  | 44 |  | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 45 | constexpr bool operator==(const GrSwizzle& that) const { return fKey == that.fKey; } | 
|  | 46 | constexpr bool operator!=(const GrSwizzle& that) const { return !(*this == that); } | 
| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 47 |  | 
|  | 48 | /** Compact representation of the swizzle suitable for a key. */ | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 49 | constexpr uint16_t asKey() const { return fKey; } | 
| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 50 |  | 
|  | 51 | /** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */ | 
|  | 52 | const char* c_str() const { return fSwiz; } | 
|  | 53 |  | 
| Brian Salomon | dc82994 | 2018-10-23 16:07:24 -0400 | [diff] [blame] | 54 | char operator[](int i) const { | 
|  | 55 | SkASSERT(i >= 0 && i < 4); | 
|  | 56 | return fSwiz[i]; | 
|  | 57 | } | 
|  | 58 |  | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 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 |  | 
|  | 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 |  | 
| bsalomon | 7f9b2e4 | 2016-01-12 13:29:26 -0800 | [diff] [blame] | 75 | /** Applies this swizzle to the input color and returns the swizzled color. */ | 
| Brian Osman | 1d5b598 | 2018-10-01 13:41:39 -0400 | [diff] [blame] | 76 | SkPMColor4f applyTo(const SkPMColor4f& color) const { | 
| Brian Osman | ce42551 | 2017-03-22 14:37:50 -0400 | [diff] [blame] | 77 | int idx; | 
|  | 78 | uint32_t key = fKey; | 
|  | 79 | // Index of the input color that should be mapped to output r. | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 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); | 
| Brian Osman | 1d5b598 | 2018-10-01 13:41:39 -0400 | [diff] [blame] | 91 | return { outR, outG, outB, outA }; | 
| Brian Osman | ce42551 | 2017-03-22 14:37:50 -0400 | [diff] [blame] | 92 | } | 
|  | 93 |  | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 94 | static constexpr GrSwizzle RGBA() { return GrSwizzle("rgba"); } | 
|  | 95 | static constexpr GrSwizzle AAAA() { return GrSwizzle("aaaa"); } | 
|  | 96 | static constexpr GrSwizzle RRRR() { return GrSwizzle("rrrr"); } | 
|  | 97 | static constexpr GrSwizzle RRRA() { return GrSwizzle("rrra"); } | 
|  | 98 | static constexpr GrSwizzle BGRA() { return GrSwizzle("bgra"); } | 
| Jim Van Verth | 69e5785 | 2018-12-05 13:38:59 -0500 | [diff] [blame] | 99 | static constexpr GrSwizzle RGRG() { return GrSwizzle("rgrg"); } | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 100 | static constexpr GrSwizzle RGB1() { return GrSwizzle("rgb1"); } | 
| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 101 |  | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 102 | private: | 
|  | 103 | char fSwiz[5]; | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 104 | uint16_t fKey; | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 105 |  | 
|  | 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); | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 112 | case '1': return k1KeyValue; | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 113 | default:  return -1; | 
| bsalomon | 6c9cd55 | 2016-01-22 07:17:34 -0800 | [diff] [blame] | 114 | } | 
|  | 115 | } | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 116 |  | 
|  | 117 | static constexpr char IToC(int idx) { | 
|  | 118 | switch (8 * idx) { | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 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; | 
| Brian Salomon | 2151165 | 2018-10-17 08:30:51 -0400 | [diff] [blame] | 125 | } | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | constexpr GrSwizzle(const char c[4]) | 
|  | 129 | : fSwiz{c[0], c[1], c[2], c[3], '\0'} | 
| Greg Daniel | f259b8b | 2019-02-14 09:03:43 -0500 | [diff] [blame] | 130 | , fKey((CToI(c[0]) << 0) | (CToI(c[1]) << 4) | (CToI(c[2]) << 8) | (CToI(c[3]) << 12)) {} | 
| bsalomon | cdee009 | 2016-01-08 13:20:12 -0800 | [diff] [blame] | 131 | }; | 
|  | 132 |  | 
|  | 133 | #endif |