OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrInvariantOutput_DEFINED | 8 #ifndef GrInvariantOutput_DEFINED |
9 #define GrInvariantOutput_DEFINED | 9 #define GrInvariantOutput_DEFINED |
10 | 10 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 , fIsLCDCoverage(io.fIsLCDCoverage) {} | 72 , fIsLCDCoverage(io.fIsLCDCoverage) {} |
73 | 73 |
74 virtual ~GrInvariantOutput() {} | 74 virtual ~GrInvariantOutput() {} |
75 | 75 |
76 enum ReadInput { | 76 enum ReadInput { |
77 kWill_ReadInput, | 77 kWill_ReadInput, |
78 kWillNot_ReadInput, | 78 kWillNot_ReadInput, |
79 }; | 79 }; |
80 | 80 |
81 void mulByUnknownOpaqueFourComponents() { | 81 void mulByUnknownOpaqueFourComponents() { |
| 82 SkDEBUGCODE(this->validate()); |
82 if (this->isOpaque()) { | 83 if (this->isOpaque()) { |
83 fValidFlags = kA_GrColorComponentFlag; | 84 fValidFlags = kA_GrColorComponentFlag; |
84 fIsSingleComponent = false; | 85 fIsSingleComponent = false; |
85 } else { | 86 } else { |
86 // Since the current state is not opaque we no longer care if the co
lor being | 87 // Since the current state is not opaque we no longer care if the co
lor being |
87 // multiplied is opaque. | 88 // multiplied is opaque. |
88 this->mulByUnknownFourComponents(); | 89 this->mulByUnknownFourComponents(); |
89 } | 90 } |
| 91 SkDEBUGCODE(this->validate()); |
90 } | 92 } |
91 | 93 |
92 void mulByUnknownFourComponents() { | 94 void mulByUnknownFourComponents() { |
| 95 SkDEBUGCODE(this->validate()); |
93 if (this->hasZeroAlpha()) { | 96 if (this->hasZeroAlpha()) { |
94 this->internalSetToTransparentBlack(); | 97 this->internalSetToTransparentBlack(); |
95 } else { | 98 } else { |
96 this->internalSetToUnknown(); | 99 this->internalSetToUnknown(); |
97 } | 100 } |
| 101 SkDEBUGCODE(this->validate()); |
98 } | 102 } |
99 | 103 |
100 void mulByUnknownSingleComponent() { | 104 void mulByUnknownSingleComponent() { |
| 105 SkDEBUGCODE(this->validate()); |
101 if (this->hasZeroAlpha()) { | 106 if (this->hasZeroAlpha()) { |
102 this->internalSetToTransparentBlack(); | 107 this->internalSetToTransparentBlack(); |
103 } else { | 108 } else { |
104 // We don't need to change fIsSingleComponent in this case | 109 // We don't need to change fIsSingleComponent in this case |
105 fValidFlags = 0; | 110 fValidFlags = 0; |
106 } | 111 } |
| 112 SkDEBUGCODE(this->validate()); |
107 } | 113 } |
108 | 114 |
109 void mulByKnownSingleComponent(uint8_t alpha) { | 115 void mulByKnownSingleComponent(uint8_t alpha) { |
| 116 SkDEBUGCODE(this->validate()); |
110 if (this->hasZeroAlpha() || 0 == alpha) { | 117 if (this->hasZeroAlpha() || 0 == alpha) { |
111 this->internalSetToTransparentBlack(); | 118 this->internalSetToTransparentBlack(); |
112 } else { | 119 } else { |
113 if (alpha != 255) { | 120 if (alpha != 255) { |
114 // Multiply color by alpha | 121 // Multiply color by alpha |
115 fColor = GrColorPackRGBA(SkMulDiv255Round(GrColorUnpackR(fColor)
, alpha), | 122 fColor = GrColorPackRGBA(SkMulDiv255Round(GrColorUnpackR(fColor)
, alpha), |
116 SkMulDiv255Round(GrColorUnpackG(fColor)
, alpha), | 123 SkMulDiv255Round(GrColorUnpackG(fColor)
, alpha), |
117 SkMulDiv255Round(GrColorUnpackB(fColor)
, alpha), | 124 SkMulDiv255Round(GrColorUnpackB(fColor)
, alpha), |
118 SkMulDiv255Round(GrColorUnpackA(fColor)
, alpha)); | 125 SkMulDiv255Round(GrColorUnpackA(fColor)
, alpha)); |
| 126 // We don't need to change fIsSingleComponent in this case |
119 } | 127 } |
120 } | 128 } |
| 129 SkDEBUGCODE(this->validate()); |
| 130 } |
| 131 |
| 132 void mulByKnownFourComponents(GrColor color) { |
| 133 SkDEBUGCODE(this->validate()); |
| 134 uint32_t a; |
| 135 if (GetAlphaAndCheckSingleChannel(color, &a)) { |
| 136 this->mulByKnownSingleComponent(a); |
| 137 } else { |
| 138 if (color != 0xffffffff) { |
| 139 fColor = GrColorPackRGBA( |
| 140 SkMulDiv255Round(GrColorUnpackR(fColor), GrColorUnpackR(colo
r)), |
| 141 SkMulDiv255Round(GrColorUnpackG(fColor), GrColorUnpackG(colo
r)), |
| 142 SkMulDiv255Round(GrColorUnpackB(fColor), GrColorUnpackB(colo
r)), |
| 143 SkMulDiv255Round(GrColorUnpackA(fColor), a)); |
| 144 if (kRGBA_GrColorComponentFlags == fValidFlags) { |
| 145 fIsSingleComponent = GetAlphaAndCheckSingleChannel(fColor, &
a); |
| 146 } |
| 147 } |
| 148 } |
| 149 SkDEBUGCODE(this->validate()); |
| 150 } |
| 151 |
| 152 // Ignores the incoming color's RGB and muls its alpha by color. |
| 153 void mulAlphaByKnownFourComponents(GrColor color) { |
| 154 SkDEBUGCODE(this->validate()); |
| 155 uint32_t a; |
| 156 if (GetAlphaAndCheckSingleChannel(color, &a)) { |
| 157 this->mulAlphaByKnownSingleComponent(a); |
| 158 } else if (fValidFlags & kA_GrColorComponentFlag) { |
| 159 GrColor preAlpha = GrColorUnpackA(fColor); |
| 160 if (0 == preAlpha) { |
| 161 this->internalSetToTransparentBlack(); |
| 162 } else { |
| 163 // We know that color has different component values |
| 164 fIsSingleComponent = false; |
| 165 fColor = GrColorPackRGBA( |
| 166 SkMulDiv255Round(preAlpha, GrColorUnpackR(color)), |
| 167 SkMulDiv255Round(preAlpha, GrColorUnpackG(color)), |
| 168 SkMulDiv255Round(preAlpha, GrColorUnpackB(color)), |
| 169 SkMulDiv255Round(preAlpha, a)); |
| 170 fValidFlags = kRGBA_GrColorComponentFlags; |
| 171 } |
| 172 } else { |
| 173 fIsSingleComponent = false; |
| 174 fValidFlags = 0; |
| 175 } |
| 176 SkDEBUGCODE(this->validate()); |
| 177 } |
| 178 |
| 179 // Ignores the incoming color's RGB and muls its alpha by the alpha param an
d sets all channels |
| 180 // equal to that value. |
| 181 void mulAlphaByKnownSingleComponent(uint8_t alpha) { |
| 182 SkDEBUGCODE(this->validate()); |
| 183 if (0 == alpha || this->hasZeroAlpha()) { |
| 184 this->internalSetToTransparentBlack(); |
| 185 } else { |
| 186 if (fValidFlags & kA_GrColorComponentFlag) { |
| 187 GrColor a = GrColorUnpackA(fColor); |
| 188 a = SkMulDiv255Round(alpha, a); |
| 189 fColor = GrColorPackRGBA(a, a, a, a); |
| 190 fValidFlags = kRGBA_GrColorComponentFlags; |
| 191 } else { |
| 192 fValidFlags = 0; |
| 193 } |
| 194 fIsSingleComponent = true; |
| 195 } |
| 196 SkDEBUGCODE(this->validate()); |
121 } | 197 } |
122 | 198 |
123 void invalidateComponents(uint8_t invalidateFlags, ReadInput readsInput) { | 199 void invalidateComponents(uint8_t invalidateFlags, ReadInput readsInput) { |
| 200 SkDEBUGCODE(this->validate()); |
124 fValidFlags &= ~invalidateFlags; | 201 fValidFlags &= ~invalidateFlags; |
125 fIsSingleComponent = false; | 202 fIsSingleComponent = false; |
126 fNonMulStageFound = true; | 203 fNonMulStageFound = true; |
127 if (kWillNot_ReadInput == readsInput) { | 204 if (kWillNot_ReadInput == readsInput) { |
128 fWillUseInputColor = false; | 205 fWillUseInputColor = false; |
129 } | 206 } |
| 207 SkDEBUGCODE(this->validate()); |
130 } | 208 } |
131 | 209 |
132 void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput) { | 210 void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput) { |
| 211 SkDEBUGCODE(this->validate()); |
133 fValidFlags = validFlags; | 212 fValidFlags = validFlags; |
134 fColor = color; | 213 fColor = color; |
135 fIsSingleComponent = false; | 214 fIsSingleComponent = false; |
136 fNonMulStageFound = true; | 215 fNonMulStageFound = true; |
137 if (kWillNot_ReadInput == readsInput) { | 216 if (kWillNot_ReadInput == readsInput) { |
138 fWillUseInputColor = false; | 217 fWillUseInputColor = false; |
139 } | 218 } |
| 219 if (kRGBA_GrColorComponentFlags == fValidFlags) { |
| 220 uint32_t a; |
| 221 if (GetAlphaAndCheckSingleChannel(color, &a)) { |
| 222 fIsSingleComponent = true; |
| 223 } |
| 224 } else if (kA_GrColorComponentFlag & fValidFlags) { |
| 225 // Assuming fColor is premul means if a is 0 the color must be all 0
s. |
| 226 if (!GrColorUnpackA(fColor)) { |
| 227 this->internalSetToTransparentBlack(); |
| 228 } |
| 229 } |
| 230 SkDEBUGCODE(this->validate()); |
140 } | 231 } |
141 | 232 |
142 void setToUnknown(ReadInput readsInput) { | 233 void setToUnknown(ReadInput readsInput) { |
| 234 SkDEBUGCODE(this->validate()); |
143 this->internalSetToUnknown(); | 235 this->internalSetToUnknown(); |
144 fNonMulStageFound= true; | 236 fNonMulStageFound= true; |
145 if (kWillNot_ReadInput == readsInput) { | 237 if (kWillNot_ReadInput == readsInput) { |
146 fWillUseInputColor = false; | 238 fWillUseInputColor = false; |
147 } | 239 } |
| 240 SkDEBUGCODE(this->validate()); |
148 } | 241 } |
149 | 242 |
150 // Temporary setter to handle LCD text correctly until we improve texture pi
xel config queries | 243 // Temporary setter to handle LCD text correctly until we improve texture pi
xel config queries |
151 // and thus can rely solely on number of coverage components for RGA vs sing
le channel coverage. | 244 // and thus can rely solely on number of coverage components for RGA vs sing
le channel coverage. |
152 void setUsingLCDCoverage() { | 245 void setUsingLCDCoverage() { |
153 fIsLCDCoverage = true; | 246 fIsLCDCoverage = true; |
154 } | 247 } |
155 | 248 |
156 GrColor color() const { return fColor; } | 249 GrColor color() const { return fColor; } |
157 uint8_t validFlags() const { return fValidFlags; } | 250 uint8_t validFlags() const { return fValidFlags; } |
158 | 251 |
159 /** | 252 /** |
160 * If isSingleComponent is true, then the flag values for r, g, b, and a mus
t all be the | 253 * If isSingleComponent is true, then the flag values for r, g, b, and a mus
t all be the |
161 * same. If the flags are all set then all color components must be equal. | 254 * same. If the flags are all set then all color components must be equal. |
162 */ | 255 */ |
163 SkDEBUGCODE(void validate() const;) | 256 SkDEBUGCODE(void validate() const;) |
164 | 257 |
165 private: | 258 private: |
166 friend class GrProcOptInfo; | 259 friend class GrProcOptInfo; |
167 | 260 |
| 261 /** Extracts the alpha channel and returns true if r,g,b == a. */ |
| 262 static bool GetAlphaAndCheckSingleChannel(GrColor color, uint32_t* alpha) { |
| 263 *alpha = GrColorUnpackA(color); |
| 264 return *alpha == GrColorUnpackR(color) && *alpha == GrColorUnpackG(color
) && |
| 265 *alpha == GrColorUnpackB(color); |
| 266 } |
| 267 |
168 void reset(GrColor color, GrColorComponentFlags flags, bool isSingleComponen
t) { | 268 void reset(GrColor color, GrColorComponentFlags flags, bool isSingleComponen
t) { |
169 fColor = color; | 269 fColor = color; |
170 fValidFlags = flags; | 270 fValidFlags = flags; |
171 fIsSingleComponent = isSingleComponent; | 271 fIsSingleComponent = isSingleComponent; |
172 fNonMulStageFound = false; | 272 fNonMulStageFound = false; |
173 fWillUseInputColor = true; | 273 fWillUseInputColor = true; |
174 } | 274 } |
175 | 275 |
176 void reset(const GrInitInvariantOutput& io) { | 276 void reset(const GrInitInvariantOutput& io) { |
177 fColor = io.fColor; | 277 fColor = io.fColor; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 uint32_t fValidFlags; | 325 uint32_t fValidFlags; |
226 bool fIsSingleComponent; | 326 bool fIsSingleComponent; |
227 bool fNonMulStageFound; | 327 bool fNonMulStageFound; |
228 bool fWillUseInputColor; | 328 bool fWillUseInputColor; |
229 bool fIsLCDCoverage; // Temorary data member until texture pixel configs are
updated | 329 bool fIsLCDCoverage; // Temorary data member until texture pixel configs are
updated |
230 | 330 |
231 }; | 331 }; |
232 | 332 |
233 #endif | 333 #endif |
234 | 334 |
OLD | NEW |