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 "glsl/GrGLSLFragmentProcessor.h" 16 #include "glsl/GrGLSLFragmentShaderBuilder.h" 17 #include "glsl/GrGLSLProgramDataManager.h" 18 #include "glsl/GrGLSLUniformHandler.h" 19 20 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const { 21 if (this->classID() != that.classID()) { 22 return false; 23 } 24 if (this->numTextureSamplers() != that.numTextureSamplers()) { 25 return false; 26 } 27 for (int i = 0; i < this->numTextureSamplers(); ++i) { 28 if (this->textureSampler(i) != that.textureSampler(i)) { 29 return false; 30 } 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 void GrFragmentProcessor::visitProxies(const std::function<void(GrSurfaceProxy*)>& func) { 50 GrFragmentProcessor::TextureAccessIter iter(this); 51 while (const TextureSampler* sampler = iter.next()) { 52 func(sampler->proxy()); 53 } 54 } 55 56 GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const { 57 GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance(); 58 glFragProc->fChildProcessors.push_back_n(fChildProcessors.count()); 59 for (int i = 0; i < fChildProcessors.count(); ++i) { 60 glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance(); 61 } 62 return glFragProc; 63 } 64 65 const GrFragmentProcessor::TextureSampler& GrFragmentProcessor::textureSampler(int i) const { 66 SkASSERT(i >= 0 && i < fTextureSamplerCnt); 67 return this->onTextureSampler(i); 68 } 69 70 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { 71 fCoordTransforms.push_back(transform); 72 fFlags |= kUsesLocalCoords_Flag; 73 SkDEBUGCODE(transform->setInProcessor();) 74 } 75 76 bool GrFragmentProcessor::instantiate(GrResourceProvider* resourceProvider) const { 77 for (int i = 0; i < fTextureSamplerCnt; ++i) { 78 if (!this->textureSampler(i).instantiate(resourceProvider)) { 79 return false; 80 } 81 } 82 83 for (int i = 0; i < this->numChildProcessors(); ++i) { 84 if (!this->childProcessor(i).instantiate(resourceProvider)) { 85 return false; 86 } 87 } 88 89 return true; 90 } 91 92 void GrFragmentProcessor::markPendingExecution() const { 93 for (int i = 0; i < fTextureSamplerCnt; ++i) { 94 auto* ref = this->textureSampler(i).proxyRef(); 95 ref->markPendingIO(); 96 ref->removeRef(); 97 } 98 for (int i = 0; i < this->numChildProcessors(); ++i) { 99 this->childProcessor(i).markPendingExecution(); 100 } 101 } 102 103 int GrFragmentProcessor::registerChildProcessor(std::unique_ptr<GrFragmentProcessor> child) { 104 if (child->usesLocalCoords()) { 105 fFlags |= kUsesLocalCoords_Flag; 106 } 107 108 int index = fChildProcessors.count(); 109 fChildProcessors.push_back(std::move(child)); 110 111 return index; 112 } 113 114 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { 115 if (this->numCoordTransforms() != that.numCoordTransforms()) { 116 return false; 117 } 118 int count = this->numCoordTransforms(); 119 for (int i = 0; i < count; ++i) { 120 if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) { 121 return false; 122 } 123 } 124 return true; 125 } 126 127 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulChildByInputAlpha( 128 std::unique_ptr<GrFragmentProcessor> fp) { 129 if (!fp) { 130 return nullptr; 131 } 132 return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn); 133 } 134 135 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::MulInputByChildAlpha( 136 std::unique_ptr<GrFragmentProcessor> fp) { 137 if (!fp) { 138 return nullptr; 139 } 140 return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kSrcIn); 141 } 142 143 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::PremulInput( 144 std::unique_ptr<GrFragmentProcessor> fp) { 145 if (!fp) { 146 return nullptr; 147 } 148 std::unique_ptr<GrFragmentProcessor> fpPipeline[] = { GrPremulInputFragmentProcessor::Make(), 149 std::move(fp) }; 150 return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 151 } 152 153 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput( 154 std::unique_ptr<GrFragmentProcessor> fp, const GrSwizzle& swizzle) { 155 class SwizzleFragmentProcessor : public GrFragmentProcessor { 156 public: 157 static std::unique_ptr<GrFragmentProcessor> Make(const GrSwizzle& swizzle) { 158 return std::unique_ptr<GrFragmentProcessor>(new SwizzleFragmentProcessor(swizzle)); 159 } 160 161 const char* name() const override { return "Swizzle"; } 162 const GrSwizzle& swizzle() const { return fSwizzle; } 163 164 std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fSwizzle); } 165 166 private: 167 SwizzleFragmentProcessor(const GrSwizzle& swizzle) 168 : INHERITED(kSwizzleFragmentProcessor_ClassID, kAll_OptimizationFlags) 169 , fSwizzle(swizzle) {} 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 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& 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 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override { 267 SkPMColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0), 268 SK_PMColor4fWHITE); 269 SkPMColor4f premulInput = SkColor4f{ input.fR, input.fG, input.fB, input.fA }.premul(); 270 return premulInput * childColor; 271 } 272 273 typedef GrFragmentProcessor INHERITED; 274 }; 275 if (!fp) { 276 return nullptr; 277 } 278 return PremulFragmentProcessor::Make(std::move(fp)); 279 } 280 281 ////////////////////////////////////////////////////////////////////////////// 282 283 std::unique_ptr<GrFragmentProcessor> GrFragmentProcessor::OverrideInput( 284 std::unique_ptr<GrFragmentProcessor> fp, const SkPMColor4f& color) { 285 class ReplaceInputFragmentProcessor : public GrFragmentProcessor { 286 public: 287 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child, 288 const SkPMColor4f& color) { 289 return std::unique_ptr<GrFragmentProcessor>( 290 new ReplaceInputFragmentProcessor(std::move(child), color)); 291 } 292 293 const char* name() const override { return "Replace Color"; } 294 295 std::unique_ptr<GrFragmentProcessor> clone() const override { 296 return Make(this->childProcessor(0).clone(), fColor); 297 } 298 299 private: 300 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 301 class GLFP : public GrGLSLFragmentProcessor { 302 public: 303 GLFP() : fHaveSetColor(false) {} 304 void emitCode(EmitArgs& args) override { 305 const char* colorName; 306 fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, 307 kHalf4_GrSLType, 308 "Color", &colorName); 309 this->emitChild(0, colorName, args); 310 } 311 312 private: 313 void onSetData(const GrGLSLProgramDataManager& pdman, 314 const GrFragmentProcessor& fp) override { 315 SkPMColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor; 316 if (!fHaveSetColor || color != fPreviousColor) { 317 pdman.set4fv(fColorUni, 1, color.vec()); 318 fPreviousColor = color; 319 fHaveSetColor = true; 320 } 321 } 322 323 GrGLSLProgramDataManager::UniformHandle fColorUni; 324 bool fHaveSetColor; 325 SkPMColor4f fPreviousColor; 326 }; 327 328 return new GLFP; 329 } 330 331 ReplaceInputFragmentProcessor(std::unique_ptr<GrFragmentProcessor> child, 332 const SkPMColor4f& color) 333 : INHERITED(kReplaceInputFragmentProcessor_ClassID, OptFlags(child.get(), color)) 334 , fColor(color) { 335 this->registerChildProcessor(std::move(child)); 336 } 337 338 static OptimizationFlags OptFlags(const GrFragmentProcessor* child, 339 const SkPMColor4f& 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 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f&) const override { 359 return ConstantOutputForConstantInput(this->childProcessor(0), fColor); 360 } 361 362 SkPMColor4f 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 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& inColor) const override { 435 SkPMColor4f color = inColor; 436 int childCnt = this->numChildProcessors(); 437 for (int i = 0; i < childCnt; ++i) { 438 color = ConstantOutputForConstantInput(this->childProcessor(i), color); 439 } 440 return color; 441 } 442 443 typedef GrFragmentProcessor INHERITED; 444 }; 445 446 if (!cnt) { 447 return nullptr; 448 } 449 if (1 == cnt) { 450 return std::move(series[0]); 451 } 452 // Run the through the series, do the invariant output processing, and look for eliminations. 453 GrProcessorAnalysisColor inputColor; 454 inputColor.setToUnknown(); 455 GrColorFragmentProcessorAnalysis info(inputColor, unique_ptr_address_as_pointer_address(series), 456 cnt); 457 SkTArray<std::unique_ptr<GrFragmentProcessor>> replacementSeries; 458 SkPMColor4f knownColor; 459 int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor); 460 if (leadingFPsToEliminate) { 461 std::unique_ptr<GrFragmentProcessor> colorFP( 462 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::InputMode::kIgnore)); 463 if (leadingFPsToEliminate == cnt) { 464 return colorFP; 465 } 466 cnt = cnt - leadingFPsToEliminate + 1; 467 replacementSeries.reserve(cnt); 468 replacementSeries.emplace_back(std::move(colorFP)); 469 for (int i = 0; i < cnt - 1; ++i) { 470 replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i])); 471 } 472 series = replacementSeries.begin(); 473 } 474 return SeriesFragmentProcessor::Make(series, cnt); 475 } 476 477 ////////////////////////////////////////////////////////////////////////////// 478 479 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) { 480 for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) { 481 fFPStack.push_back(&pipeline.getFragmentProcessor(i)); 482 } 483 } 484 485 GrFragmentProcessor::Iter::Iter(const GrPaint& paint) { 486 for (int i = paint.numCoverageFragmentProcessors() - 1; i >= 0; --i) { 487 fFPStack.push_back(paint.getCoverageFragmentProcessor(i)); 488 } 489 for (int i = paint.numColorFragmentProcessors() - 1; i >= 0; --i) { 490 fFPStack.push_back(paint.getColorFragmentProcessor(i)); 491 } 492 } 493 494 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() { 495 if (fFPStack.empty()) { 496 return nullptr; 497 } 498 const GrFragmentProcessor* back = fFPStack.back(); 499 fFPStack.pop_back(); 500 for (int i = back->numChildProcessors() - 1; i >= 0; --i) { 501 fFPStack.push_back(&back->childProcessor(i)); 502 } 503 return back; 504 } 505 506 /////////////////////////////////////////////////////////////////////////////////////////////////// 507 508 GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy, 509 const GrSamplerState& samplerState) { 510 this->reset(std::move(proxy), samplerState); 511 } 512 513 GrFragmentProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy, 514 GrSamplerState::Filter filterMode, 515 GrSamplerState::WrapMode wrapXAndY) { 516 this->reset(std::move(proxy), filterMode, wrapXAndY); 517 } 518 519 void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy, 520 const GrSamplerState& samplerState) { 521 fProxyRef.setProxy(std::move(proxy), kRead_GrIOType); 522 fSamplerState = samplerState; 523 fSamplerState.setFilterMode(SkTMin(samplerState.filter(), this->proxy()->highestFilterMode())); 524 } 525 526 void GrFragmentProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy, 527 GrSamplerState::Filter filterMode, 528 GrSamplerState::WrapMode wrapXAndY) { 529 fProxyRef.setProxy(std::move(proxy), kRead_GrIOType); 530 filterMode = SkTMin(filterMode, this->proxy()->highestFilterMode()); 531 fSamplerState = GrSamplerState(wrapXAndY, filterMode); 532 } 533