OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrFragmentProcessor.h" | 9 #include "GrFragmentProcessor.h" |
10 #include "GrCoordTransform.h" | 10 #include "GrCoordTransform.h" |
11 #include "gl/GrGLFragmentProcessor.h" | 11 #include "gl/GrGLFragmentProcessor.h" |
| 12 #include "gl/builders/GrGLProgramBuilder.h" |
12 #include "effects/GrXfermodeFragmentProcessor.h" | 13 #include "effects/GrXfermodeFragmentProcessor.h" |
13 | 14 |
14 GrFragmentProcessor::~GrFragmentProcessor() { | 15 GrFragmentProcessor::~GrFragmentProcessor() { |
15 // If we got here then our ref count must have reached zero, so we will have
converted refs | 16 // If we got here then our ref count must have reached zero, so we will have
converted refs |
16 // to pending executions for all children. | 17 // to pending executions for all children. |
17 for (int i = 0; i < fChildProcessors.count(); ++i) { | 18 for (int i = 0; i < fChildProcessors.count(); ++i) { |
18 fChildProcessors[i]->completedExecution(); | 19 fChildProcessors[i]->completedExecution(); |
19 } | 20 } |
20 } | 21 } |
21 | 22 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 116 } |
116 int count = this->numTransforms(); | 117 int count = this->numTransforms(); |
117 for (int i = 0; i < count; ++i) { | 118 for (int i = 0; i < count; ++i) { |
118 if (this->coordTransform(i) != that.coordTransform(i)) { | 119 if (this->coordTransform(i) != that.coordTransform(i)) { |
119 return false; | 120 return false; |
120 } | 121 } |
121 } | 122 } |
122 return true; | 123 return true; |
123 } | 124 } |
124 | 125 |
125 const GrFragmentProcessor* GrFragmentProcessor::MulOuputByInputAlpha( | 126 const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputAlpha( |
126 const GrFragmentProcessor* fp) { | 127 const GrFragmentProcessor* fp) { |
| 128 if (!fp) { |
| 129 return nullptr; |
| 130 } |
127 return GrXfermodeFragmentProcessor::CreateFromDstProcessor(fp, SkXfermode::k
DstIn_Mode); | 131 return GrXfermodeFragmentProcessor::CreateFromDstProcessor(fp, SkXfermode::k
DstIn_Mode); |
128 } | 132 } |
129 | 133 |
| 134 const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputUnpremulColor( |
| 135 const GrFragmentProcessor* fp) { |
| 136 |
| 137 class PremulFragmentProcessor : public GrFragmentProcessor { |
| 138 public: |
| 139 PremulFragmentProcessor(const GrFragmentProcessor* processor) { |
| 140 this->initClassID<PremulFragmentProcessor>(); |
| 141 this->registerChildProcessor(processor); |
| 142 } |
| 143 |
| 144 const char* name() const override { return "Premultiply"; } |
| 145 |
| 146 private: |
| 147 GrGLFragmentProcessor* onCreateGLInstance() const override { |
| 148 class GLFP : public GrGLFragmentProcessor { |
| 149 public: |
| 150 GLFP() {} |
| 151 |
| 152 void emitCode(EmitArgs& args) override { |
| 153 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentS
haderBuilder(); |
| 154 this->emitChild(0, nullptr, args); |
| 155 fsBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColo
r, |
| 156 args.fInputColor
); |
| 157 fsBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, arg
s.fInputColor); |
| 158 } |
| 159 }; |
| 160 return new GLFP; |
| 161 } |
| 162 |
| 163 void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) cons
t override {} |
| 164 |
| 165 bool onIsEqual(const GrFragmentProcessor&) const override { return true;
} |
| 166 |
| 167 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 168 // TODO: Add a helper to GrInvariantOutput that handles multiplying
by color with flags? |
| 169 if (!(inout->validFlags() & kA_GrColorComponentFlag)) { |
| 170 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); |
| 171 return; |
| 172 } |
| 173 |
| 174 GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentF
lags, false); |
| 175 this->childProcessor(0).computeInvariantOutput(&childOutput); |
| 176 |
| 177 if (0 == GrColorUnpackA(inout->color()) || 0 == GrColorUnpackA(child
Output.color())) { |
| 178 inout->mulByKnownFourComponents(0x0); |
| 179 return; |
| 180 } |
| 181 GrColorComponentFlags commonFlags = childOutput.validFlags() & inout
->validFlags(); |
| 182 GrColor c0 = GrPremulColor(inout->color()); |
| 183 GrColor c1 = childOutput.color(); |
| 184 GrColor color = 0x0; |
| 185 if (commonFlags & kR_GrColorComponentFlag) { |
| 186 color |= SkMulDiv255Round(GrColorUnpackR(c0), GrColorUnpackR(c1)
) << |
| 187 GrColor_SHIFT_R; |
| 188 } |
| 189 if (commonFlags & kG_GrColorComponentFlag) { |
| 190 color |= SkMulDiv255Round(GrColorUnpackG(c0), GrColorUnpackG(c1)
) << |
| 191 GrColor_SHIFT_G; |
| 192 } |
| 193 if (commonFlags & kB_GrColorComponentFlag) { |
| 194 color |= SkMulDiv255Round(GrColorUnpackB(c0), GrColorUnpackB(c1)
) << |
| 195 GrColor_SHIFT_B; |
| 196 } |
| 197 inout->setToOther(commonFlags, color, GrInvariantOutput::kWill_ReadI
nput); |
| 198 } |
| 199 }; |
| 200 if (!fp) { |
| 201 return nullptr; |
| 202 } |
| 203 return new PremulFragmentProcessor(fp); |
| 204 } |
| 205 |
| 206 ////////////////////////////////////////////////////////////////////////////// |
| 207 |
| 208 const GrFragmentProcessor* GrFragmentProcessor::OverrideInput(const GrFragmentPr
ocessor* fp, |
| 209 GrColor color) { |
| 210 class ReplaceInputFragmentProcessor : public GrFragmentProcessor { |
| 211 public: |
| 212 ReplaceInputFragmentProcessor(const GrFragmentProcessor* child, GrColor
color) |
| 213 : fColor(color) { |
| 214 this->initClassID<ReplaceInputFragmentProcessor>(); |
| 215 this->registerChildProcessor(child); |
| 216 } |
| 217 |
| 218 const char* name() const override { return "Replace Color"; } |
| 219 |
| 220 GrGLFragmentProcessor* onCreateGLInstance() const override { |
| 221 class GLFP : public GrGLFragmentProcessor { |
| 222 public: |
| 223 GLFP() : fHaveSetColor(false) {} |
| 224 void emitCode(EmitArgs& args) override { |
| 225 const char* colorName; |
| 226 fColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kF
ragment_Visibility, |
| 227 kVec4f_GrSLType, kDefa
ult_GrSLPrecision, |
| 228 "Color", &colorName); |
| 229 this->emitChild(0, colorName, args); |
| 230 } |
| 231 |
| 232 private: |
| 233 void onSetData(const GrGLProgramDataManager& pdman, |
| 234 const GrProcessor& fp) override { |
| 235 GrColor color = fp.cast<ReplaceInputFragmentProcessor>().fCo
lor; |
| 236 if (!fHaveSetColor || color != fPreviousColor) { |
| 237 static const GrGLfloat scale = 1.f / 255.f; |
| 238 GrGLfloat floatColor[4] = { |
| 239 GrColorUnpackR(color) * scale, |
| 240 GrColorUnpackG(color) * scale, |
| 241 GrColorUnpackB(color) * scale, |
| 242 GrColorUnpackA(color) * scale, |
| 243 }; |
| 244 pdman.set4fv(fColorUni, 1, floatColor); |
| 245 fPreviousColor = color; |
| 246 fHaveSetColor = true; |
| 247 } |
| 248 } |
| 249 |
| 250 GrGLProgramDataManager::UniformHandle fColorUni; |
| 251 bool fHaveSetColor; |
| 252 GrColor fPreviousColor; |
| 253 }; |
| 254 |
| 255 return new GLFP; |
| 256 } |
| 257 |
| 258 private: |
| 259 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder*
b) const override {} |
| 260 |
| 261 bool onIsEqual(const GrFragmentProcessor& that) const override { |
| 262 return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor; |
| 263 } |
| 264 |
| 265 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 266 inout->setToOther(kRGBA_GrColorComponentFlags, fColor, |
| 267 GrInvariantOutput::kWillNot_ReadInput); |
| 268 this->childProcessor(0).computeInvariantOutput(inout); |
| 269 } |
| 270 |
| 271 GrColor fColor; |
| 272 }; |
| 273 |
| 274 GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags, false); |
| 275 fp->computeInvariantOutput(&childOut); |
| 276 if (childOut.willUseInputColor()) { |
| 277 return new ReplaceInputFragmentProcessor(fp, color); |
| 278 } else { |
| 279 return SkRef(fp); |
| 280 } |
| 281 } |
OLD | NEW |