1 /* 2 * Copyright 2015 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 #include "GrFragmentProcessor.h" 9 #include "GrCoordTransform.h" 10 #include "GrPipeline.h" 11 #include "GrPipelineAnalysis.h" 12 #include "effects/GrConstColorProcessor.h" 13 #include "effects/GrXfermodeFragmentProcessor.h" 14 #include "glsl/GrGLSLFragmentProcessor.h" 15 #include "glsl/GrGLSLFragmentShaderBuilder.h" 16 #include "glsl/GrGLSLProgramDataManager.h" 17 #include "glsl/GrGLSLUniformHandler.h" 18 19 GrFragmentProcessor::~GrFragmentProcessor() { 20 // If we got here then our ref count must have reached zero, so we will have converted refs 21 // to pending executions for all children. 22 for (int i = 0; i < fChildProcessors.count(); ++i) { 23 fChildProcessors[i]->completedExecution(); 24 } 25 } 26 27 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const { 28 if (this->classID() != that.classID() || 29 !this->hasSameSamplersAndAccesses(that)) { 30 return false; 31 } 32 if (!this->hasSameTransforms(that)) { 33 return false; 34 } 35 if (!this->onIsEqual(that)) { 36 return false; 37 } 38 if (this->numChildProcessors() != that.numChildProcessors()) { 39 return false; 40 } 41 for (int i = 0; i < this->numChildProcessors(); ++i) { 42 if (!this->childProcessor(i).isEqual(that.childProcessor(i))) { 43 return false; 44 } 45 } 46 return true; 47 } 48 49 GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const { 50 GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance(); 51 glFragProc->fChildProcessors.push_back_n(fChildProcessors.count()); 52 for (int i = 0; i < fChildProcessors.count(); ++i) { 53 glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance(); 54 } 55 return glFragProc; 56 } 57 58 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { 59 fCoordTransforms.push_back(transform); 60 fFlags |= kUsesLocalCoords_Flag; 61 SkDEBUGCODE(transform->setInProcessor();) 62 } 63 64 int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child) { 65 this->combineRequiredFeatures(*child); 66 67 if (child->usesLocalCoords()) { 68 fFlags |= kUsesLocalCoords_Flag; 69 } 70 if (child->usesDistanceVectorField()) { 71 fFlags |= kUsesDistanceVectorField_Flag; 72 } 73 74 int index = fChildProcessors.count(); 75 fChildProcessors.push_back(child.release()); 76 77 return index; 78 } 79 80 void GrFragmentProcessor::notifyRefCntIsZero() const { 81 // See comment above GrProgramElement for a detailed explanation of why we do this. 82 for (int i = 0; i < fChildProcessors.count(); ++i) { 83 fChildProcessors[i]->addPendingExecution(); 84 fChildProcessors[i]->unref(); 85 } 86 } 87 88 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { 89 if (this->numCoordTransforms() != that.numCoordTransforms()) { 90 return false; 91 } 92 int count = this->numCoordTransforms(); 93 for (int i = 0; i < count; ++i) { 94 if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) { 95 return false; 96 } 97 } 98 return true; 99 } 100 101 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputAlpha( 102 sk_sp<GrFragmentProcessor> fp) { 103 if (!fp) { 104 return nullptr; 105 } 106 return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn); 107 } 108 109 namespace { 110 111 class PremulInputFragmentProcessor : public GrFragmentProcessor { 112 public: 113 PremulInputFragmentProcessor() 114 : INHERITED(kPreservesOpaqueInput_OptimizationFlag | 115 kConstantOutputForConstantInput_OptimizationFlag) { 116 this->initClassID<PremulInputFragmentProcessor>(); 117 } 118 119 const char* name() const override { return "PremultiplyInput"; } 120 121 private: 122 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 123 class GLFP : public GrGLSLFragmentProcessor { 124 public: 125 void emitCode(EmitArgs& args) override { 126 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 127 128 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor); 129 fragBuilder->codeAppendf("%s.rgb *= %s.a;", 130 args.fOutputColor, args.fInputColor); 131 } 132 }; 133 return new GLFP; 134 } 135 136 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 137 138 bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 139 140 GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 141 return input.premul(); 142 } 143 144 typedef GrFragmentProcessor INHERITED; 145 }; 146 147 class UnpremulInputFragmentProcessor : public GrFragmentProcessor { 148 public: 149 UnpremulInputFragmentProcessor() 150 : INHERITED(kPreservesOpaqueInput_OptimizationFlag | 151 kConstantOutputForConstantInput_OptimizationFlag) { 152 this->initClassID<UnpremulInputFragmentProcessor>(); 153 } 154 155 const char* name() const override { return "UnpremultiplyInput"; } 156 157 private: 158 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 159 class GLFP : public GrGLSLFragmentProcessor { 160 public: 161 void emitCode(EmitArgs& args) override { 162 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 163 164 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor); 165 fragBuilder->codeAppendf("float invAlpha = %s.a <= 0.0 ? 0.0 : 1.0 / %s.a;", 166 args.fInputColor, args.fInputColor); 167 fragBuilder->codeAppendf("%s.rgb *= invAlpha;", args.fOutputColor); 168 } 169 }; 170 return new GLFP; 171 } 172 173 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 174 175 bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 176 177 GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 178 return input.unpremul(); 179 } 180 181 typedef GrFragmentProcessor INHERITED; 182 }; 183 184 } 185 186 sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProcessor> fp) { 187 if (!fp) { 188 return nullptr; 189 } 190 sk_sp<GrFragmentProcessor> fpPipeline[] = { sk_make_sp<PremulInputFragmentProcessor>(), fp}; 191 return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 192 } 193 194 sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(sk_sp<GrFragmentProcessor> fp) { 195 if (!fp) { 196 return nullptr; 197 } 198 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<PremulInputFragmentProcessor>() }; 199 return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 200 } 201 202 sk_sp<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(sk_sp<GrFragmentProcessor> fp) { 203 if (!fp) { 204 return nullptr; 205 } 206 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<UnpremulInputFragmentProcessor>() }; 207 return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 208 } 209 210 sk_sp<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(sk_sp<GrFragmentProcessor> fp, 211 const GrSwizzle& swizzle) { 212 class SwizzleFragmentProcessor : public GrFragmentProcessor { 213 public: 214 SwizzleFragmentProcessor(const GrSwizzle& swizzle) 215 : INHERITED(kAll_OptimizationFlags) 216 , fSwizzle(swizzle) { 217 this->initClassID<SwizzleFragmentProcessor>(); 218 } 219 220 const char* name() const override { return "Swizzle"; } 221 const GrSwizzle& swizzle() const { return fSwizzle; } 222 223 private: 224 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 225 class GLFP : public GrGLSLFragmentProcessor { 226 public: 227 void emitCode(EmitArgs& args) override { 228 const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>(); 229 const GrSwizzle& swizzle = sfp.swizzle(); 230 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 231 232 fragBuilder->codeAppendf("%s = %s.%s;", 233 args.fOutputColor, args.fInputColor, swizzle.c_str()); 234 } 235 }; 236 return new GLFP; 237 } 238 239 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { 240 b->add32(fSwizzle.asKey()); 241 } 242 243 bool onIsEqual(const GrFragmentProcessor& other) const override { 244 const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>(); 245 return fSwizzle == sfp.fSwizzle; 246 } 247 248 GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 249 return fSwizzle.applyTo(input); 250 } 251 252 GrSwizzle fSwizzle; 253 254 typedef GrFragmentProcessor INHERITED; 255 }; 256 257 if (!fp) { 258 return nullptr; 259 } 260 if (GrSwizzle::RGBA() == swizzle) { 261 return fp; 262 } 263 sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<SwizzleFragmentProcessor>(swizzle) }; 264 return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 265 } 266 267 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput( 268 sk_sp<GrFragmentProcessor> fp) { 269 270 class PremulFragmentProcessor : public GrFragmentProcessor { 271 public: 272 PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor) 273 : INHERITED(OptFlags(processor.get())) { 274 this->initClassID<PremulFragmentProcessor>(); 275 this->registerChildProcessor(processor); 276 } 277 278 const char* name() const override { return "Premultiply"; } 279 280 private: 281 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 282 class GLFP : public GrGLSLFragmentProcessor { 283 public: 284 void emitCode(EmitArgs& args) override { 285 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 286 this->emitChild(0, nullptr, args); 287 fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor, 288 args.fInputColor); 289 fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor); 290 } 291 }; 292 return new GLFP; 293 } 294 295 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 296 297 bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 298 299 static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) { 300 OptimizationFlags flags = kNone_OptimizationFlags; 301 if (inner->preservesOpaqueInput()) { 302 flags |= kPreservesOpaqueInput_OptimizationFlag; 303 } 304 if (inner->hasConstantOutputForConstantInput()) { 305 flags |= kConstantOutputForConstantInput_OptimizationFlag; 306 } 307 return flags; 308 } 309 310 GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 311 GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0), 312 GrColor4f::OpaqueWhite()); 313 return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0], 314 input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1], 315 input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2], 316 input.fRGBA[3] * childColor.fRGBA[3]); 317 } 318 319 typedef GrFragmentProcessor INHERITED; 320 }; 321 if (!fp) { 322 return nullptr; 323 } 324 return sk_sp<GrFragmentProcessor>(new PremulFragmentProcessor(std::move(fp))); 325 } 326 327 ////////////////////////////////////////////////////////////////////////////// 328 329 sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentProcessor> fp, 330 GrColor4f color) { 331 class ReplaceInputFragmentProcessor : public GrFragmentProcessor { 332 public: 333 ReplaceInputFragmentProcessor(sk_sp<GrFragmentProcessor> child, GrColor4f color) 334 : INHERITED(OptFlags(child.get(), color)), fColor(color) { 335 this->initClassID<ReplaceInputFragmentProcessor>(); 336 this->registerChildProcessor(std::move(child)); 337 } 338 339 const char* name() const override { return "Replace Color"; } 340 341 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 342 class GLFP : public GrGLSLFragmentProcessor { 343 public: 344 GLFP() : fHaveSetColor(false) {} 345 void emitCode(EmitArgs& args) override { 346 const char* colorName; 347 fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, 348 kVec4f_GrSLType, 349 kDefault_GrSLPrecision, 350 "Color", &colorName); 351 this->emitChild(0, colorName, args); 352 } 353 354 private: 355 void onSetData(const GrGLSLProgramDataManager& pdman, 356 const GrProcessor& fp) override { 357 GrColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor; 358 if (!fHaveSetColor || color != fPreviousColor) { 359 pdman.set4fv(fColorUni, 1, color.fRGBA); 360 fPreviousColor = color; 361 fHaveSetColor = true; 362 } 363 } 364 365 GrGLSLProgramDataManager::UniformHandle fColorUni; 366 bool fHaveSetColor; 367 GrColor4f fPreviousColor; 368 }; 369 370 return new GLFP; 371 } 372 373 private: 374 static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f color) { 375 OptimizationFlags childFlags = child->optimizationFlags(); 376 OptimizationFlags flags = kNone_OptimizationFlags; 377 if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) { 378 flags |= kConstantOutputForConstantInput_OptimizationFlag; 379 } 380 if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) { 381 flags |= kPreservesOpaqueInput_OptimizationFlag; 382 } 383 return flags; 384 } 385 386 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override 387 {} 388 389 bool onIsEqual(const GrFragmentProcessor& that) const override { 390 return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor; 391 } 392 393 GrColor4f constantOutputForConstantInput(GrColor4f) const override { 394 return ConstantOutputForConstantInput(this->childProcessor(0), fColor); 395 } 396 397 GrColor4f fColor; 398 399 typedef GrFragmentProcessor INHERITED; 400 }; 401 402 return sk_sp<GrFragmentProcessor>(new ReplaceInputFragmentProcessor(std::move(fp), color)); 403 } 404 405 sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProcessor>* series, 406 int cnt) { 407 class SeriesFragmentProcessor : public GrFragmentProcessor { 408 public: 409 SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt) 410 : INHERITED(OptFlags(children, cnt)) { 411 SkASSERT(cnt > 1); 412 this->initClassID<SeriesFragmentProcessor>(); 413 for (int i = 0; i < cnt; ++i) { 414 this->registerChildProcessor(std::move(children[i])); 415 } 416 } 417 418 const char* name() const override { return "Series"; } 419 420 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 421 class GLFP : public GrGLSLFragmentProcessor { 422 public: 423 void emitCode(EmitArgs& args) override { 424 // First guy's input might be nil. 425 SkString temp("out0"); 426 this->emitChild(0, args.fInputColor, &temp, args); 427 SkString input = temp; 428 for (int i = 1; i < this->numChildProcessors() - 1; ++i) { 429 temp.printf("out%d", i); 430 this->emitChild(i, input.c_str(), &temp, args); 431 input = temp; 432 } 433 // Last guy writes to our output variable. 434 this->emitChild(this->numChildProcessors() - 1, input.c_str(), args); 435 } 436 }; 437 return new GLFP; 438 } 439 private: 440 static OptimizationFlags OptFlags(sk_sp<GrFragmentProcessor>* children, int cnt) { 441 OptimizationFlags flags = kAll_OptimizationFlags; 442 for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) { 443 flags &= children[i]->optimizationFlags(); 444 } 445 return flags; 446 } 447 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 448 449 bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 450 451 GrColor4f constantOutputForConstantInput(GrColor4f color) const override { 452 int childCnt = this->numChildProcessors(); 453 for (int i = 0; i < childCnt; ++i) { 454 color = ConstantOutputForConstantInput(this->childProcessor(i), color); 455 } 456 return color; 457 } 458 459 typedef GrFragmentProcessor INHERITED; 460 }; 461 462 if (!cnt) { 463 return nullptr; 464 } 465 if (1 == cnt) { 466 return series[0]; 467 } 468 // Run the through the series, do the invariant output processing, and look for eliminations. 469 GrColorFragmentProcessorAnalysis info; 470 info.analyzeProcessors(sk_sp_address_as_pointer_address(series), cnt); 471 SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries; 472 GrColor4f knownColor; 473 int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor); 474 if (leadingFPsToEliminate) { 475 sk_sp<GrFragmentProcessor> colorFP( 476 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::kIgnore_InputMode)); 477 if (leadingFPsToEliminate == cnt) { 478 return colorFP; 479 } 480 cnt = cnt - leadingFPsToEliminate + 1; 481 replacementSeries.reserve(cnt); 482 replacementSeries.emplace_back(std::move(colorFP)); 483 for (int i = 0; i < cnt - 1; ++i) { 484 replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i])); 485 } 486 series = replacementSeries.begin(); 487 } 488 return sk_sp<GrFragmentProcessor>(new SeriesFragmentProcessor(series, cnt)); 489 } 490 491 ////////////////////////////////////////////////////////////////////////////// 492 493 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) { 494 for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) { 495 fFPStack.push_back(&pipeline.getFragmentProcessor(i)); 496 } 497 } 498 499 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() { 500 if (fFPStack.empty()) { 501 return nullptr; 502 } 503 const GrFragmentProcessor* back = fFPStack.back(); 504 fFPStack.pop_back(); 505 for (int i = back->numChildProcessors() - 1; i >= 0; --i) { 506 fFPStack.push_back(&back->childProcessor(i)); 507 } 508 return back; 509 } 510 511