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