OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 GrProcessor_DEFINED | 8 #ifndef GrProcessor_DEFINED |
9 #define GrProcessor_DEFINED | 9 #define GrProcessor_DEFINED |
10 | 10 |
11 #include "GrBackendProcessorFactory.h" | 11 #include "GrBackendProcessorFactory.h" |
12 #include "GrColor.h" | 12 #include "GrColor.h" |
13 #include "GrProcessorUnitTest.h" | 13 #include "GrProcessorUnitTest.h" |
14 #include "GrProgramElement.h" | 14 #include "GrProgramElement.h" |
15 #include "GrTextureAccess.h" | 15 #include "GrTextureAccess.h" |
| 16 #include "SkMath.h" |
16 | 17 |
17 class GrContext; | 18 class GrContext; |
18 class GrCoordTransform; | 19 class GrCoordTransform; |
19 | 20 |
20 /** Provides custom shader code to the Ganesh shading pipeline. GrProcessor obje
cts *must* be | 21 /** Provides custom shader code to the Ganesh shading pipeline. GrProcessor obje
cts *must* be |
21 immutable: after being constructed, their fields may not change. | 22 immutable: after being constructed, their fields may not change. |
22 | 23 |
23 Dynamically allocated GrProcessors are managed by a per-thread memory pool.
The ref count of an | 24 Dynamically allocated GrProcessors are managed by a per-thread memory pool.
The ref count of an |
24 processor must reach 0 before the thread terminates and the pool is destroye
d. To create a | 25 processor must reach 0 before the thread terminates and the pool is destroye
d. To create a |
25 static processor use the helper macro GR_CREATE_STATIC_PROCESSOR declared be
low. | 26 static processor use the helper macro GR_CREATE_STATIC_PROCESSOR declared be
low. |
26 */ | 27 */ |
27 class GrProcessor : public GrProgramElement { | 28 class GrProcessor : public GrProgramElement { |
28 public: | 29 public: |
29 SK_DECLARE_INST_COUNT(GrProcessor) | 30 SK_DECLARE_INST_COUNT(GrProcessor) |
30 | 31 |
31 virtual ~GrProcessor(); | 32 virtual ~GrProcessor(); |
32 | 33 |
33 struct InvariantOutput{ | 34 struct InvariantOutput{ |
34 InvariantOutput() : fColor(0), fValidFlags(0), fIsSingleComponent(false)
, | 35 InvariantOutput() : fColor(0), fValidFlags(0), fIsSingleComponent(false)
, |
35 fNonMulStageFound(false) {} | 36 fNonMulStageFound(false), fWillUseInputColor(true) {
} |
| 37 |
| 38 enum ReadInput { |
| 39 kWill_ReadInput, |
| 40 kWillNot_ReadInput, |
| 41 }; |
36 | 42 |
37 void mulByUnknownOpaqueColor() { | 43 void mulByUnknownOpaqueColor() { |
38 if (this->isOpaque()) { | 44 if (this->isOpaque()) { |
39 fValidFlags = kA_GrColorComponentFlag; | 45 fValidFlags = kA_GrColorComponentFlag; |
40 fIsSingleComponent = false; | 46 fIsSingleComponent = false; |
41 } else { | 47 } else { |
42 // Since the current state is not opaque we no longer care if th
e color being | 48 // Since the current state is not opaque we no longer care if th
e color being |
43 // multiplied is opaque. | 49 // multiplied is opaque. |
44 this->mulByUnknownColor(); | 50 this->mulByUnknownColor(); |
45 } | 51 } |
46 } | 52 } |
47 | 53 |
48 void mulByUnknownColor() { | 54 void mulByUnknownColor() { |
49 if (this->hasZeroAlpha()) { | 55 if (this->hasZeroAlpha()) { |
50 this->internalSetToTransparentBlack(); | 56 this->internalSetToTransparentBlack(); |
51 } else { | 57 } else { |
52 this->internalSetToUnknown(); | 58 this->internalSetToUnknown(); |
53 } | 59 } |
54 } | 60 } |
55 | 61 |
56 void mulByUnknownAlpha() { | 62 void mulByUnknownAlpha() { |
57 if (this->hasZeroAlpha()) { | 63 if (this->hasZeroAlpha()) { |
58 this->internalSetToTransparentBlack(); | 64 this->internalSetToTransparentBlack(); |
59 } else { | 65 } else { |
60 // We don't need to change fIsSingleComponent in this case | 66 // We don't need to change fIsSingleComponent in this case |
61 fValidFlags = 0; | 67 fValidFlags = 0; |
62 } | 68 } |
63 } | 69 } |
64 | 70 |
65 void invalidateComponents(uint8_t invalidateFlags) { | 71 void mulByKnownAlpha(uint8_t alpha) { |
| 72 if (this->hasZeroAlpha() || 0 == alpha) { |
| 73 this->internalSetToTransparentBlack(); |
| 74 } else { |
| 75 if (alpha != 255) { |
| 76 // Multiply color by alpha |
| 77 fColor = GrColorPackRGBA(SkMulDiv255Round(GrColorUnpackR(fCo
lor), alpha), |
| 78 SkMulDiv255Round(GrColorUnpackG(fCo
lor), alpha), |
| 79 SkMulDiv255Round(GrColorUnpackB(fCo
lor), alpha), |
| 80 SkMulDiv255Round(GrColorUnpackA(fCo
lor), alpha)); |
| 81 } |
| 82 } |
| 83 } |
| 84 |
| 85 void invalidateComponents(uint8_t invalidateFlags, ReadInput readsInput)
{ |
66 fValidFlags &= ~invalidateFlags; | 86 fValidFlags &= ~invalidateFlags; |
67 fIsSingleComponent = false; | 87 fIsSingleComponent = false; |
| 88 if (kWillNot_ReadInput == readsInput) { |
| 89 fWillUseInputColor = false; |
| 90 } |
68 } | 91 } |
69 | 92 |
70 void setToTransparentBlack() { | 93 void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput)
{ |
71 this->internalSetToTransparentBlack(); | |
72 fNonMulStageFound = true; | |
73 } | |
74 | |
75 void setToOther(uint8_t validFlags, GrColor color) { | |
76 fValidFlags = validFlags; | 94 fValidFlags = validFlags; |
77 fColor = color; | 95 fColor = color; |
78 fIsSingleComponent = false; | 96 fIsSingleComponent = false; |
79 fNonMulStageFound = true; | 97 fNonMulStageFound = true; |
| 98 if (kWillNot_ReadInput == readsInput) { |
| 99 fWillUseInputColor = false; |
| 100 } |
80 } | 101 } |
81 | 102 |
82 void setToUnknown() { | 103 void setToUnknown(ReadInput readsInput) { |
83 this->internalSetToUnknown(); | 104 this->internalSetToUnknown(); |
84 fNonMulStageFound= true; | 105 fNonMulStageFound= true; |
| 106 if (kWillNot_ReadInput == readsInput) { |
| 107 fWillUseInputColor = false; |
| 108 } |
85 } | 109 } |
86 | 110 |
87 bool isOpaque() const { | 111 bool isOpaque() const { |
88 return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUn
packA(fColor)); | 112 return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUn
packA(fColor)); |
89 } | 113 } |
90 | 114 |
91 bool isSolidWhite() const { | 115 bool isSolidWhite() const { |
92 return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF ==
fColor); | 116 return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF ==
fColor); |
93 } | 117 } |
94 | 118 |
(...skipping 27 matching lines...) Expand all Loading... |
122 * If alpha is valid, check that any valid R,G,B values are <= A | 146 * If alpha is valid, check that any valid R,G,B values are <= A |
123 */ | 147 */ |
124 SkDEBUGCODE(bool validPreMulColor() const;) | 148 SkDEBUGCODE(bool validPreMulColor() const;) |
125 | 149 |
126 // Friended class that have "controller" code which loop over stages cal
ling | 150 // Friended class that have "controller" code which loop over stages cal
ling |
127 // computeInvarianteOutput(). These controllers may need to manually adj
ust the internal | 151 // computeInvarianteOutput(). These controllers may need to manually adj
ust the internal |
128 // members of InvariantOutput | 152 // members of InvariantOutput |
129 friend class GrDrawState; | 153 friend class GrDrawState; |
130 friend class GrOptDrawState; | 154 friend class GrOptDrawState; |
131 friend class GrPaint; | 155 friend class GrPaint; |
| 156 friend class GrProcessor; |
132 | 157 |
133 GrColor fColor; | 158 GrColor fColor; |
134 uint32_t fValidFlags; | 159 uint32_t fValidFlags; |
135 bool fIsSingleComponent; | 160 bool fIsSingleComponent; |
136 bool fNonMulStageFound; | 161 bool fNonMulStageFound; |
| 162 bool fWillUseInputColor; |
137 }; | 163 }; |
138 | 164 |
139 /** | 165 /** |
140 * This function is used to perform optimizations. When called the invarient
Ouput param | 166 * This function is used to perform optimizations. When called the invarient
Ouput param |
141 * indicate whether the input components to this processor in the FS will ha
ve known values. | 167 * indicate whether the input components to this processor in the FS will ha
ve known values. |
142 * In inout the validFlags member is a bitfield of GrColorComponentFlags. Th
e isSingleComponent | 168 * In inout the validFlags member is a bitfield of GrColorComponentFlags. Th
e isSingleComponent |
143 * member indicates whether the input will be 1 or 4 bytes. The function upd
ates the members of | 169 * member indicates whether the input will be 1 or 4 bytes. The function upd
ates the members of |
144 * inout to indicate known values of its output. A component of the color me
mber only has | 170 * inout to indicate known values of its output. A component of the color me
mber only has |
145 * meaning if the corresponding bit in validFlags is set. | 171 * meaning if the corresponding bit in validFlags is set. |
146 */ | 172 */ |
147 void computeInvariantOutput(InvariantOutput* inout) const { | 173 void computeInvariantOutput(InvariantOutput* inout) const { |
| 174 inout->fWillUseInputColor = true; |
148 this->onComputeInvariantOutput(inout); | 175 this->onComputeInvariantOutput(inout); |
149 #ifdef SK_DEBUG | 176 #ifdef SK_DEBUG |
150 inout->validate(); | 177 inout->validate(); |
151 #endif | 178 #endif |
152 } | 179 } |
153 | 180 |
154 /** This object, besides creating back-end-specific helper objects, is used
for run-time-type- | 181 /** This object, besides creating back-end-specific helper objects, is used
for run-time-type- |
155 identification. The factory should be an instance of templated class, | 182 identification. The factory should be an instance of templated class, |
156 GrTBackendProcessorFactory. It is templated on the subclass of GrProcess
or. The subclass | 183 GrTBackendProcessorFactory. It is templated on the subclass of GrProcess
or. The subclass |
157 must have a nested type (or typedef) named GLProcessor which will be the
subclass of | 184 must have a nested type (or typedef) named GLProcessor which will be the
subclass of |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 /** | 264 /** |
238 * This creates a processor outside of the memory pool. The processor's destruct
or will be called | 265 * This creates a processor outside of the memory pool. The processor's destruct
or will be called |
239 * at global destruction time. NAME will be the name of the created instance. | 266 * at global destruction time. NAME will be the name of the created instance. |
240 */ | 267 */ |
241 #define GR_CREATE_STATIC_PROCESSOR(NAME, PROC_CLASS, ARGS)
\ | 268 #define GR_CREATE_STATIC_PROCESSOR(NAME, PROC_CLASS, ARGS)
\ |
242 static SkAlignedSStorage<sizeof(PROC_CLASS)> g_##NAME##_Storage;
\ | 269 static SkAlignedSStorage<sizeof(PROC_CLASS)> g_##NAME##_Storage;
\ |
243 static PROC_CLASS* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), PROC_CLAS
S, ARGS); \ | 270 static PROC_CLASS* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), PROC_CLAS
S, ARGS); \ |
244 static SkAutoTDestroy<GrProcessor> NAME##_ad(NAME); | 271 static SkAutoTDestroy<GrProcessor> NAME##_ad(NAME); |
245 | 272 |
246 #endif | 273 #endif |
OLD | NEW |