Skia
2DGraphicsLibrary
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GrInvariantOutput.h
1 /*
2  * Copyright 2014 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 GrInvariantOutput_DEFINED
9 #define GrInvariantOutput_DEFINED
10 
11 #include "GrColor.h"
12 
15  : fValidFlags(kNone_GrColorComponentFlags)
16  , fColor(0)
17  , fIsSingleComponent(false)
18  , fIsLCDCoverage(false) {}
19 
20  void setKnownFourComponents(GrColor color) {
21  fColor = color;
22  fValidFlags = kRGBA_GrColorComponentFlags;
23  fIsSingleComponent = false;
24  }
25 
26  void setUnknownFourComponents() {
27  fValidFlags = kNone_GrColorComponentFlags;
28  fIsSingleComponent = false;
29  }
30 
31  void setUnknownOpaqueFourComponents() {
32  fColor = 0xffU << GrColor_SHIFT_A;
33  fValidFlags = kA_GrColorComponentFlag;
34  fIsSingleComponent = false;
35  }
36 
37  void setKnownSingleComponent(uint8_t alpha) {
38  fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
39  fValidFlags = kRGBA_GrColorComponentFlags;
40  fIsSingleComponent = true;
41  }
42 
43  void setUnknownSingleComponent() {
44  fValidFlags = kNone_GrColorComponentFlags;
45  fIsSingleComponent = true;
46  }
47 
48  void setUsingLCDCoverage() { fIsLCDCoverage = true; }
49 
50  GrColorComponentFlags fValidFlags;
51  GrColor fColor;
52  bool fIsSingleComponent;
53  bool fIsLCDCoverage; // Temorary data member until texture pixel configs are
54  // updated
55 };
56 
58 public:
59  GrInvariantOutput(GrColor color, GrColorComponentFlags flags, bool isSingleComponent)
60  : fColor(color)
61  , fValidFlags(flags)
62  , fIsSingleComponent(isSingleComponent)
63  , fNonMulStageFound(false)
64  , fWillUseInputColor(true)
65  , fIsLCDCoverage(false) {}
66 
68  : fColor(io.fColor)
69  , fValidFlags(io.fValidFlags)
70  , fIsSingleComponent(io.fIsSingleComponent)
71  , fNonMulStageFound(false)
72  , fWillUseInputColor(false)
73  , fIsLCDCoverage(io.fIsLCDCoverage) {}
74 
75  virtual ~GrInvariantOutput() {}
76 
77  enum ReadInput {
78  kWill_ReadInput,
79  kWillNot_ReadInput,
80  };
81 
82  void mulByUnknownOpaqueFourComponents() {
83  SkDEBUGCODE(this->validate());
84  if (this->isOpaque()) {
85  fValidFlags = kA_GrColorComponentFlag;
86  fIsSingleComponent = false;
87  } else {
88  // Since the current state is not opaque we no longer care if the color being
89  // multiplied is opaque.
90  this->mulByUnknownFourComponents();
91  }
92  SkDEBUGCODE(this->validate());
93  }
94 
95  void mulByUnknownFourComponents() {
96  SkDEBUGCODE(this->validate());
97  if (this->hasZeroAlpha()) {
98  this->internalSetToTransparentBlack();
99  } else {
100  this->internalSetToUnknown();
101  }
102  SkDEBUGCODE(this->validate());
103  }
104 
105  void mulByUnknownSingleComponent() {
106  SkDEBUGCODE(this->validate());
107  if (this->hasZeroAlpha()) {
108  this->internalSetToTransparentBlack();
109  } else {
110  // We don't need to change fIsSingleComponent in this case
111  fValidFlags = kNone_GrColorComponentFlags;
112  }
113  SkDEBUGCODE(this->validate());
114  }
115 
116  void mulByKnownSingleComponent(uint8_t alpha) {
117  SkDEBUGCODE(this->validate());
118  if (this->hasZeroAlpha() || 0 == alpha) {
119  this->internalSetToTransparentBlack();
120  } else {
121  if (alpha != 255) {
122  // Multiply color by alpha
123  fColor = GrColorPackRGBA(SkMulDiv255Round(GrColorUnpackR(fColor), alpha),
124  SkMulDiv255Round(GrColorUnpackG(fColor), alpha),
125  SkMulDiv255Round(GrColorUnpackB(fColor), alpha),
126  SkMulDiv255Round(GrColorUnpackA(fColor), alpha));
127  // We don't need to change fIsSingleComponent in this case
128  }
129  }
130  SkDEBUGCODE(this->validate());
131  }
132 
133  void mulByKnownFourComponents(GrColor color) {
134  SkDEBUGCODE(this->validate());
135  uint32_t a;
136  if (GetAlphaAndCheckSingleChannel(color, &a)) {
137  this->mulByKnownSingleComponent(a);
138  } else {
139  if (color != 0xffffffff) {
140  fColor = GrColorPackRGBA(
141  SkMulDiv255Round(GrColorUnpackR(fColor), GrColorUnpackR(color)),
142  SkMulDiv255Round(GrColorUnpackG(fColor), GrColorUnpackG(color)),
143  SkMulDiv255Round(GrColorUnpackB(fColor), GrColorUnpackB(color)),
144  SkMulDiv255Round(GrColorUnpackA(fColor), a));
145  if (kRGBA_GrColorComponentFlags == fValidFlags) {
146  fIsSingleComponent = GetAlphaAndCheckSingleChannel(fColor, &a);
147  }
148  }
149  }
150  SkDEBUGCODE(this->validate());
151  }
152 
153  // Ignores the incoming color's RGB and muls its alpha by color.
154  void mulAlphaByKnownFourComponents(GrColor color) {
155  SkDEBUGCODE(this->validate());
156  uint32_t a;
157  if (GetAlphaAndCheckSingleChannel(color, &a)) {
158  this->mulAlphaByKnownSingleComponent(a);
159  } else if (fValidFlags & kA_GrColorComponentFlag) {
160  GrColor preAlpha = GrColorUnpackA(fColor);
161  if (0 == preAlpha) {
162  this->internalSetToTransparentBlack();
163  } else {
164  // We know that color has different component values
165  fIsSingleComponent = false;
166  fColor = GrColorPackRGBA(
167  SkMulDiv255Round(preAlpha, GrColorUnpackR(color)),
168  SkMulDiv255Round(preAlpha, GrColorUnpackG(color)),
169  SkMulDiv255Round(preAlpha, GrColorUnpackB(color)),
170  SkMulDiv255Round(preAlpha, a));
171  fValidFlags = kRGBA_GrColorComponentFlags;
172  }
173  } else {
174  fIsSingleComponent = false;
175  fValidFlags = kNone_GrColorComponentFlags;
176  }
177  SkDEBUGCODE(this->validate());
178  }
179 
180  // Ignores the incoming color's RGB and muls its alpha by the alpha param and sets all channels
181  // equal to that value.
182  void mulAlphaByKnownSingleComponent(uint8_t alpha) {
183  SkDEBUGCODE(this->validate());
184  if (0 == alpha || this->hasZeroAlpha()) {
185  this->internalSetToTransparentBlack();
186  } else {
187  if (fValidFlags & kA_GrColorComponentFlag) {
188  GrColor a = GrColorUnpackA(fColor);
189  a = SkMulDiv255Round(alpha, a);
190  fColor = GrColorPackRGBA(a, a, a, a);
191  fValidFlags = kRGBA_GrColorComponentFlags;
192  } else {
193  fValidFlags = kNone_GrColorComponentFlags;
194  }
195  fIsSingleComponent = true;
196  }
197  SkDEBUGCODE(this->validate());
198  }
199 
200  void premulFourChannelColor() {
201  SkDEBUGCODE(this->validate());
202  SkASSERT(!fIsSingleComponent);
203  fNonMulStageFound = true;
204  if (!(fValidFlags & kA_GrColorComponentFlag)) {
205  fValidFlags = kNone_GrColorComponentFlags;
206  } else {
207  fColor = GrPremulColor(fColor);
208  }
209  SkDEBUGCODE(this->validate());
210  }
211 
212  void invalidateComponents(GrColorComponentFlags invalidateFlags, ReadInput readsInput) {
213  SkDEBUGCODE(this->validate());
214  fValidFlags = (fValidFlags & ~invalidateFlags);
215  fIsSingleComponent = false;
216  fNonMulStageFound = true;
217  if (kWillNot_ReadInput == readsInput) {
218  fWillUseInputColor = false;
219  }
220  SkDEBUGCODE(this->validate());
221  }
222 
223  void setToOther(GrColorComponentFlags validFlags, GrColor color, ReadInput readsInput) {
224  SkDEBUGCODE(this->validate());
225  fValidFlags = validFlags;
226  fColor = color;
227  fIsSingleComponent = false;
228  fNonMulStageFound = true;
229  if (kWillNot_ReadInput == readsInput) {
230  fWillUseInputColor = false;
231  }
232  if (kRGBA_GrColorComponentFlags == fValidFlags) {
233  uint32_t a;
234  if (GetAlphaAndCheckSingleChannel(color, &a)) {
235  fIsSingleComponent = true;
236  }
237  }
238  SkDEBUGCODE(this->validate());
239  }
240 
241  void setToUnknown(ReadInput readsInput) {
242  SkDEBUGCODE(this->validate());
243  this->internalSetToUnknown();
244  fNonMulStageFound= true;
245  if (kWillNot_ReadInput == readsInput) {
246  fWillUseInputColor = false;
247  }
248  SkDEBUGCODE(this->validate());
249  }
250 
251  // Temporary setter to handle LCD text correctly until we improve texture pixel config queries
252  // and thus can rely solely on number of coverage components for RGA vs single channel coverage.
253  void setUsingLCDCoverage() {
254  fIsLCDCoverage = true;
255  }
256 
257  GrColor color() const { return fColor; }
258  GrColorComponentFlags validFlags() const { return fValidFlags; }
259  bool willUseInputColor() const { return fWillUseInputColor; }
260 
265  SkDEBUGCODE(void validate() const;)
266 
267 private:
268  friend class GrProcOptInfo;
269 
271  static bool GetAlphaAndCheckSingleChannel(GrColor color, uint32_t* alpha) {
272  *alpha = GrColorUnpackA(color);
273  return *alpha == GrColorUnpackR(color) && *alpha == GrColorUnpackG(color) &&
274  *alpha == GrColorUnpackB(color);
275  }
276 
277  void reset(GrColor color, GrColorComponentFlags flags, bool isSingleComponent) {
278  fColor = color;
279  fValidFlags = flags;
280  fIsSingleComponent = isSingleComponent;
281  fNonMulStageFound = false;
282  fWillUseInputColor = true;
283  }
284 
285  void reset(const GrInitInvariantOutput& io) {
286  fColor = io.fColor;
287  fValidFlags = io.fValidFlags;
288  fIsSingleComponent = io.fIsSingleComponent;
289  fNonMulStageFound = false;
290  fWillUseInputColor = true;
291  fIsLCDCoverage = io.fIsLCDCoverage;
292  }
293 
294  void internalSetToTransparentBlack() {
295  fValidFlags = kRGBA_GrColorComponentFlags;
296  fColor = 0;
297  fIsSingleComponent = true;
298  }
299 
300  void internalSetToUnknown() {
301  fValidFlags = kNone_GrColorComponentFlags;
302  fIsSingleComponent = false;
303  }
304 
305  bool hasZeroAlpha() const {
306  return ((fValidFlags & kA_GrColorComponentFlag) && 0 == GrColorUnpackA(fColor));
307  }
308 
309  bool isOpaque() const {
310  return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor));
311  }
312 
313  bool isSolidWhite() const {
314  return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor);
315  }
316 
317  bool isSingleComponent() const { return fIsSingleComponent; }
318 
319  void resetWillUseInputColor() { fWillUseInputColor = true; }
320 
321  bool allStagesMulInput() const { return !fNonMulStageFound; }
322  void resetNonMulStageFound() { fNonMulStageFound = false; }
323 
324  bool isLCDCoverage() const { return fIsLCDCoverage; }
325 
326  SkDEBUGCODE(bool colorComponentsAllEqual() const;)
330  SkDEBUGCODE(bool validPreMulColor() const;)
331 
332  GrColor fColor;
333  GrColorComponentFlags fValidFlags;
334  bool fIsSingleComponent;
335  bool fNonMulStageFound;
336  bool fWillUseInputColor;
337  bool fIsLCDCoverage; // Temorary data member until texture pixel configs are updated
338 
339 };
340 
341 #endif
342 
Definition: GrInvariantOutput.h:13
Definition: GrInvariantOutput.h:57
SkDEBUGCODE(bool colorComponentsAllEqual() const ;) SkDEBUGCODE(bool validPreMulColor() const
If alpha is valid, check that any valid R,G,B values are <= A.
Definition: GrInvariantOutput.h:271