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