| 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 #include "SkMath.h" |
| 17 | 17 |
| 18 class GrContext; | 18 class GrContext; |
| 19 class GrCoordTransform; | 19 class GrCoordTransform; |
| 20 class GrInvariantOutput; |
| 20 | 21 |
| 21 /** Provides custom shader code to the Ganesh shading pipeline. GrProcessor obje
cts *must* be | 22 /** Provides custom shader code to the Ganesh shading pipeline. GrProcessor obje
cts *must* be |
| 22 immutable: after being constructed, their fields may not change. | 23 immutable: after being constructed, their fields may not change. |
| 23 | 24 |
| 24 Dynamically allocated GrProcessors are managed by a per-thread memory pool.
The ref count of an | 25 Dynamically allocated GrProcessors are managed by a per-thread memory pool.
The ref count of an |
| 25 processor must reach 0 before the thread terminates and the pool is destroye
d. To create a | 26 processor must reach 0 before the thread terminates and the pool is destroye
d. To create a |
| 26 static processor use the helper macro GR_CREATE_STATIC_PROCESSOR declared be
low. | 27 static processor use the helper macro GR_CREATE_STATIC_PROCESSOR declared be
low. |
| 27 */ | 28 */ |
| 28 class GrProcessor : public GrProgramElement { | 29 class GrProcessor : public GrProgramElement { |
| 29 public: | 30 public: |
| 30 SK_DECLARE_INST_COUNT(GrProcessor) | 31 SK_DECLARE_INST_COUNT(GrProcessor) |
| 31 | 32 |
| 32 virtual ~GrProcessor(); | 33 virtual ~GrProcessor(); |
| 33 | 34 |
| 34 struct InvariantOutput{ | |
| 35 InvariantOutput() : fColor(0), fValidFlags(0), fIsSingleComponent(false)
, | |
| 36 fNonMulStageFound(false), fWillUseInputColor(true) {
} | |
| 37 | |
| 38 enum ReadInput { | |
| 39 kWill_ReadInput, | |
| 40 kWillNot_ReadInput, | |
| 41 }; | |
| 42 | |
| 43 void mulByUnknownOpaqueColor() { | |
| 44 if (this->isOpaque()) { | |
| 45 fValidFlags = kA_GrColorComponentFlag; | |
| 46 fIsSingleComponent = false; | |
| 47 } else { | |
| 48 // Since the current state is not opaque we no longer care if th
e color being | |
| 49 // multiplied is opaque. | |
| 50 this->mulByUnknownColor(); | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 void mulByUnknownColor() { | |
| 55 if (this->hasZeroAlpha()) { | |
| 56 this->internalSetToTransparentBlack(); | |
| 57 } else { | |
| 58 this->internalSetToUnknown(); | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 void mulByUnknownAlpha() { | |
| 63 if (this->hasZeroAlpha()) { | |
| 64 this->internalSetToTransparentBlack(); | |
| 65 } else { | |
| 66 // We don't need to change fIsSingleComponent in this case | |
| 67 fValidFlags = 0; | |
| 68 } | |
| 69 } | |
| 70 | |
| 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)
{ | |
| 86 fValidFlags &= ~invalidateFlags; | |
| 87 fIsSingleComponent = false; | |
| 88 if (kWillNot_ReadInput == readsInput) { | |
| 89 fWillUseInputColor = false; | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 void setToOther(uint8_t validFlags, GrColor color, ReadInput readsInput)
{ | |
| 94 fValidFlags = validFlags; | |
| 95 fColor = color; | |
| 96 fIsSingleComponent = false; | |
| 97 fNonMulStageFound = true; | |
| 98 if (kWillNot_ReadInput == readsInput) { | |
| 99 fWillUseInputColor = false; | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 void setToUnknown(ReadInput readsInput) { | |
| 104 this->internalSetToUnknown(); | |
| 105 fNonMulStageFound= true; | |
| 106 if (kWillNot_ReadInput == readsInput) { | |
| 107 fWillUseInputColor = false; | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 bool isOpaque() const { | |
| 112 return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUn
packA(fColor)); | |
| 113 } | |
| 114 | |
| 115 bool isSolidWhite() const { | |
| 116 return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF ==
fColor); | |
| 117 } | |
| 118 | |
| 119 GrColor color() const { return fColor; } | |
| 120 uint8_t validFlags() const { return fValidFlags; } | |
| 121 | |
| 122 /** | |
| 123 * If isSingleComponent is true, then the flag values for r, g, b, and a
must all be the | |
| 124 * same. If the flags are all set then all color components must be equa
l. | |
| 125 */ | |
| 126 SkDEBUGCODE(void validate() const;) | |
| 127 | |
| 128 private: | |
| 129 void internalSetToTransparentBlack() { | |
| 130 fValidFlags = kRGBA_GrColorComponentFlags; | |
| 131 fColor = 0; | |
| 132 fIsSingleComponent = true; | |
| 133 } | |
| 134 | |
| 135 void internalSetToUnknown() { | |
| 136 fValidFlags = 0; | |
| 137 fIsSingleComponent = false; | |
| 138 } | |
| 139 | |
| 140 bool hasZeroAlpha() const { | |
| 141 return ((fValidFlags & kA_GrColorComponentFlag) && 0 == GrColorUnpac
kA(fColor)); | |
| 142 } | |
| 143 | |
| 144 SkDEBUGCODE(bool colorComponentsAllEqual() const;) | |
| 145 /** | |
| 146 * If alpha is valid, check that any valid R,G,B values are <= A | |
| 147 */ | |
| 148 SkDEBUGCODE(bool validPreMulColor() const;) | |
| 149 | |
| 150 // Friended class that have "controller" code which loop over stages cal
ling | |
| 151 // computeInvarianteOutput(). These controllers may need to manually adj
ust the internal | |
| 152 // members of InvariantOutput | |
| 153 friend class GrDrawState; | |
| 154 friend class GrOptDrawState; | |
| 155 friend class GrPaint; | |
| 156 friend class GrProcessor; | |
| 157 | |
| 158 GrColor fColor; | |
| 159 uint32_t fValidFlags; | |
| 160 bool fIsSingleComponent; | |
| 161 bool fNonMulStageFound; | |
| 162 bool fWillUseInputColor; | |
| 163 }; | |
| 164 | |
| 165 /** | 35 /** |
| 166 * This function is used to perform optimizations. When called the invarient
Ouput param | 36 * This function is used to perform optimizations. When called the invarient
Ouput param |
| 167 * indicate whether the input components to this processor in the FS will ha
ve known values. | 37 * indicate whether the input components to this processor in the FS will ha
ve known values. |
| 168 * In inout the validFlags member is a bitfield of GrColorComponentFlags. Th
e isSingleComponent | 38 * In inout the validFlags member is a bitfield of GrColorComponentFlags. Th
e isSingleComponent |
| 169 * member indicates whether the input will be 1 or 4 bytes. The function upd
ates the members of | 39 * member indicates whether the input will be 1 or 4 bytes. The function upd
ates the members of |
| 170 * inout to indicate known values of its output. A component of the color me
mber only has | 40 * inout to indicate known values of its output. A component of the color me
mber only has |
| 171 * meaning if the corresponding bit in validFlags is set. | 41 * meaning if the corresponding bit in validFlags is set. |
| 172 */ | 42 */ |
| 173 void computeInvariantOutput(InvariantOutput* inout) const { | 43 void computeInvariantOutput(GrInvariantOutput* inout) const; |
| 174 inout->fWillUseInputColor = true; | |
| 175 this->onComputeInvariantOutput(inout); | |
| 176 #ifdef SK_DEBUG | |
| 177 inout->validate(); | |
| 178 #endif | |
| 179 } | |
| 180 | 44 |
| 181 /** This object, besides creating back-end-specific helper objects, is used
for run-time-type- | 45 /** This object, besides creating back-end-specific helper objects, is used
for run-time-type- |
| 182 identification. The factory should be an instance of templated class, | 46 identification. The factory should be an instance of templated class, |
| 183 GrTBackendProcessorFactory. It is templated on the subclass of GrProcess
or. The subclass | 47 GrTBackendProcessorFactory. It is templated on the subclass of GrProcess
or. The subclass |
| 184 must have a nested type (or typedef) named GLProcessor which will be the
subclass of | 48 must have a nested type (or typedef) named GLProcessor which will be the
subclass of |
| 185 GrGLProcessor created by the factory. | 49 GrGLProcessor created by the factory. |
| 186 | 50 |
| 187 Example: | 51 Example: |
| 188 class MyCustomProcessor : public GrProcessor { | 52 class MyCustomProcessor : public GrProcessor { |
| 189 ... | 53 ... |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 bool hasSameTextureAccesses(const GrProcessor&) const; | 104 bool hasSameTextureAccesses(const GrProcessor&) const; |
| 241 | 105 |
| 242 /** | 106 /** |
| 243 * If the prcoessor will generate a backend-specific processor that will rea
d the fragment | 107 * If the prcoessor will generate a backend-specific processor that will rea
d the fragment |
| 244 * position in the FS then it must call this method from its constructor. Ot
herwise, the | 108 * position in the FS then it must call this method from its constructor. Ot
herwise, the |
| 245 * request to access the fragment position will be denied. | 109 * request to access the fragment position will be denied. |
| 246 */ | 110 */ |
| 247 void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; } | 111 void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; } |
| 248 | 112 |
| 249 private: | 113 private: |
| 250 | |
| 251 /** | 114 /** |
| 252 * Subclass implements this to support getConstantColorComponents(...). | 115 * Subclass implements this to support getConstantColorComponents(...). |
| 253 */ | 116 */ |
| 254 virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0; | 117 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0; |
| 255 | 118 |
| 256 SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; | 119 SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; |
| 257 bool fWillReadFragmentPosition; | 120 bool fWillReadFragmentPosition; |
| 258 | 121 |
| 259 typedef GrProgramElement INHERITED; | 122 typedef GrProgramElement INHERITED; |
| 260 }; | 123 }; |
| 261 | 124 |
| 262 | 125 |
| 263 /** | 126 /** |
| 264 * This creates a processor outside of the memory pool. The processor's destruct
or will be called | 127 * This creates a processor outside of the memory pool. The processor's destruct
or will be called |
| 265 * at global destruction time. NAME will be the name of the created instance. | 128 * at global destruction time. NAME will be the name of the created instance. |
| 266 */ | 129 */ |
| 267 #define GR_CREATE_STATIC_PROCESSOR(NAME, PROC_CLASS, ARGS)
\ | 130 #define GR_CREATE_STATIC_PROCESSOR(NAME, PROC_CLASS, ARGS)
\ |
| 268 static SkAlignedSStorage<sizeof(PROC_CLASS)> g_##NAME##_Storage;
\ | 131 static SkAlignedSStorage<sizeof(PROC_CLASS)> g_##NAME##_Storage;
\ |
| 269 static PROC_CLASS* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), PROC_CLAS
S, ARGS); \ | 132 static PROC_CLASS* NAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), PROC_CLAS
S, ARGS); \ |
| 270 static SkAutoTDestroy<GrProcessor> NAME##_ad(NAME); | 133 static SkAutoTDestroy<GrProcessor> NAME##_ad(NAME); |
| 271 | 134 |
| 272 #endif | 135 #endif |
| OLD | NEW |