1bf87730c7da80616f6ea17765290dbd2c147a669bsalomon/* 2bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* Copyright 2015 Google Inc. 3bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* 4bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* Use of this source code is governed by a BSD-style license that can be 5bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* found in the LICENSE file. 6bf87730c7da80616f6ea17765290dbd2c147a669bsalomon*/ 7bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 8bf87730c7da80616f6ea17765290dbd2c147a669bsalomon#include "GrFragmentProcessor.h" 9bf87730c7da80616f6ea17765290dbd2c147a669bsalomon#include "GrCoordTransform.h" 10a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon#include "GrPipeline.h" 11c0b642ca48d58416409e555549434066f09692b7Brian Salomon#include "GrPipelineAnalysis.h" 12c0b642ca48d58416409e555549434066f09692b7Brian Salomon#include "effects/GrConstColorProcessor.h" 13c0b642ca48d58416409e555549434066f09692b7Brian Salomon#include "effects/GrXfermodeFragmentProcessor.h" 1464c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h" 152d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h" 16018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h" 177ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h" 18bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 19bf87730c7da80616f6ea17765290dbd2c147a669bsalomonGrFragmentProcessor::~GrFragmentProcessor() { 20bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // If we got here then our ref count must have reached zero, so we will have converted refs 21bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // to pending executions for all children. 22bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < fChildProcessors.count(); ++i) { 23bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fChildProcessors[i]->completedExecution(); 24bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 25bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 26bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 277312ff87f64f31d741989a60d993bcaa4bb20523bsalomonbool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const { 28bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (this->classID() != that.classID() || 29f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon !this->hasSameSamplersAndAccesses(that)) { 30bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 31bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 327312ff87f64f31d741989a60d993bcaa4bb20523bsalomon if (!this->hasSameTransforms(that)) { 33bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 34bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 35bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (!this->onIsEqual(that)) { 36bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 37bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 38bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (this->numChildProcessors() != that.numChildProcessors()) { 39bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 40bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 41bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < this->numChildProcessors(); ++i) { 427312ff87f64f31d741989a60d993bcaa4bb20523bsalomon if (!this->childProcessor(i).isEqual(that.childProcessor(i))) { 43bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 44bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 45bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 46bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return true; 47bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 48bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 4957d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const { 5057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance(); 51bf87730c7da80616f6ea17765290dbd2c147a669bsalomon glFragProc->fChildProcessors.push_back_n(fChildProcessors.count()); 52bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < fChildProcessors.count(); ++i) { 5357d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance(); 54bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 55bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return glFragProc; 56bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 57bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 58bf87730c7da80616f6ea17765290dbd2c147a669bsalomonvoid GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { 59bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fCoordTransforms.push_back(transform); 60587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon fFlags |= kUsesLocalCoords_Flag; 61bf87730c7da80616f6ea17765290dbd2c147a669bsalomon SkDEBUGCODE(transform->setInProcessor();) 62bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 63bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 6406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemanint GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child) { 6587332103c605dc3e0f76c0d1250a76c4ff71fddccdalton this->combineRequiredFeatures(*child); 66bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 67bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (child->usesLocalCoords()) { 68587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon fFlags |= kUsesLocalCoords_Flag; 69bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 709b03e7b29d963ea333a66dc5353e94f6391eb899dvonbeck if (child->usesDistanceVectorField()) { 71587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon fFlags |= kUsesDistanceVectorField_Flag; 729b03e7b29d963ea333a66dc5353e94f6391eb899dvonbeck } 73bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 7406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman int index = fChildProcessors.count(); 7506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman fChildProcessors.push_back(child.release()); 7606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman 77bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return index; 78bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 79bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 80bf87730c7da80616f6ea17765290dbd2c147a669bsalomonvoid GrFragmentProcessor::notifyRefCntIsZero() const { 81bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // See comment above GrProgramElement for a detailed explanation of why we do this. 82bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < fChildProcessors.count(); ++i) { 83bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fChildProcessors[i]->addPendingExecution(); 84bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fChildProcessors[i]->unref(); 85bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 86bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 87bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 88bf87730c7da80616f6ea17765290dbd2c147a669bsalomonbool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { 89a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon if (this->numCoordTransforms() != that.numCoordTransforms()) { 90bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 91bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 92a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon int count = this->numCoordTransforms(); 93bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < count; ++i) { 9467c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) { 95bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 96bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 97bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 98bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return true; 99bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 100bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 10106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputAlpha( 10206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrFragmentProcessor> fp) { 103f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (!fp) { 104f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return nullptr; 105f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 1067d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn); 107bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 108bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 109de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmannamespace { 110de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 111de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmanclass PremulInputFragmentProcessor : public GrFragmentProcessor { 112de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmanpublic: 113de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman PremulInputFragmentProcessor() 114de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman : INHERITED(kPreservesOpaqueInput_OptimizationFlag | 115de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman kConstantOutputForConstantInput_OptimizationFlag) { 116de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman this->initClassID<PremulInputFragmentProcessor>(); 117de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 118c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck 119de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman const char* name() const override { return "PremultiplyInput"; } 120de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 121de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmanprivate: 122de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 123de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman class GLFP : public GrGLSLFragmentProcessor { 124de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman public: 125de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman void emitCode(EmitArgs& args) override { 126de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 127de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 128de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor); 129de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman fragBuilder->codeAppendf("%s.rgb *= %s.a;", 130de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman args.fOutputColor, args.fInputColor); 131de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 132de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman }; 133de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return new GLFP; 134de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 135c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck 136de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 137de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 138de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 139c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck 140de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 141de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return input.premul(); 142de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 143c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck 144de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman typedef GrFragmentProcessor INHERITED; 145de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman}; 146c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck 147de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmanclass UnpremulInputFragmentProcessor : public GrFragmentProcessor { 148de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmanpublic: 149de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman UnpremulInputFragmentProcessor() 150de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman : INHERITED(kPreservesOpaqueInput_OptimizationFlag | 151de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman kConstantOutputForConstantInput_OptimizationFlag) { 152de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman this->initClassID<UnpremulInputFragmentProcessor>(); 153de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 154de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 155de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman const char* name() const override { return "UnpremultiplyInput"; } 156de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 157de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmanprivate: 158de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 159de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman class GLFP : public GrGLSLFragmentProcessor { 160de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman public: 161de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman void emitCode(EmitArgs& args) override { 162de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 163de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 164de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor); 165de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman fragBuilder->codeAppendf("float invAlpha = %s.a <= 0.0 ? 0.0 : 1.0 / %s.a;", 166de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman args.fInputColor, args.fInputColor); 167de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman fragBuilder->codeAppendf("%s.rgb *= invAlpha;", args.fOutputColor); 168de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 169de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman }; 170de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return new GLFP; 171de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 172de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 173de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 174de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 175de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 176de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 177de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 178de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return input.unpremul(); 179de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 180de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 181de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman typedef GrFragmentProcessor INHERITED; 182de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman}; 183587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 184de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman} 185de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 186de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmansk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProcessor> fp) { 187c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck if (!fp) { 188c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck return nullptr; 189c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck } 190c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck sk_sp<GrFragmentProcessor> fpPipeline[] = { sk_make_sp<PremulInputFragmentProcessor>(), fp}; 191c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 192c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck} 193c526da94e4f2dc0c8521099dad2118c5d6b8da4advonbeck 194de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmansk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(sk_sp<GrFragmentProcessor> fp) { 195de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman if (!fp) { 196de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return nullptr; 197de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 198de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<PremulInputFragmentProcessor>() }; 199de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 200de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman} 201de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 202de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmansk_sp<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(sk_sp<GrFragmentProcessor> fp) { 203de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman if (!fp) { 204de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return nullptr; 205de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman } 206de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<UnpremulInputFragmentProcessor>() }; 207de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 208de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman} 209de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman 210ce425510a07632f14b7b779ec3864f719cb4326bBrian Osmansk_sp<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(sk_sp<GrFragmentProcessor> fp, 211ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman const GrSwizzle& swizzle) { 212ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman class SwizzleFragmentProcessor : public GrFragmentProcessor { 213ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman public: 214ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman SwizzleFragmentProcessor(const GrSwizzle& swizzle) 215ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman : INHERITED(kAll_OptimizationFlags) 216ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman , fSwizzle(swizzle) { 217ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman this->initClassID<SwizzleFragmentProcessor>(); 218ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 219ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 220ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman const char* name() const override { return "Swizzle"; } 221ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman const GrSwizzle& swizzle() const { return fSwizzle; } 222ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 223ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman private: 224ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 225ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman class GLFP : public GrGLSLFragmentProcessor { 226ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman public: 227ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman void emitCode(EmitArgs& args) override { 228ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>(); 229ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman const GrSwizzle& swizzle = sfp.swizzle(); 230ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 231ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 232ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman fragBuilder->codeAppendf("%s = %s.%s;", 233ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman args.fOutputColor, args.fInputColor, swizzle.c_str()); 234ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 235ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman }; 236ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman return new GLFP; 237ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 238ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 239ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override { 240ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman b->add32(fSwizzle.asKey()); 241ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 242ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 243ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman bool onIsEqual(const GrFragmentProcessor& other) const override { 244ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>(); 245ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman return fSwizzle == sfp.fSwizzle; 246ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 247ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 248ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 249ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman return fSwizzle.applyTo(input); 250ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 251ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 252ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman GrSwizzle fSwizzle; 253ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 254ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman typedef GrFragmentProcessor INHERITED; 255ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman }; 256ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 257ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman if (!fp) { 258ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman return nullptr; 259ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 260ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman if (GrSwizzle::RGBA() == swizzle) { 261ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman return fp; 262ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman } 263ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<SwizzleFragmentProcessor>(swizzle) }; 264ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman return GrFragmentProcessor::RunInSeries(fpPipeline, 2); 265ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman} 266ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman 26722af73f2a5fd40fd9f991e35f7a216e924464cd4Brian Salomonsk_sp<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput( 26822af73f2a5fd40fd9f991e35f7a216e924464cd4Brian Salomon sk_sp<GrFragmentProcessor> fp) { 269f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 270f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon class PremulFragmentProcessor : public GrFragmentProcessor { 271f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 272587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor) 273587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon : INHERITED(OptFlags(processor.get())) { 274f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->initClassID<PremulFragmentProcessor>(); 275f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->registerChildProcessor(processor); 276f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 277f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 278f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const char* name() const override { return "Premultiply"; } 279f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 280f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon private: 28157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 28264c4728c70001ed074fecf5c4e083781987b12e9egdaniel class GLFP : public GrGLSLFragmentProcessor { 283f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 284f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon void emitCode(EmitArgs& args) override { 2858528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 286f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->emitChild(0, nullptr, args); 2874ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor, 288f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon args.fInputColor); 2894ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor); 290f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 291f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 292f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return new GLFP; 293f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 294f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 29594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 296f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 297f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 298f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 299587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) { 300587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon OptimizationFlags flags = kNone_OptimizationFlags; 301587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon if (inner->preservesOpaqueInput()) { 302587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon flags |= kPreservesOpaqueInput_OptimizationFlag; 303587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 304587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon if (inner->hasConstantOutputForConstantInput()) { 305587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon flags |= kConstantOutputForConstantInput_OptimizationFlag; 306587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 307587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return flags; 308587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 309f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 310587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon GrColor4f constantOutputForConstantInput(GrColor4f input) const override { 311587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0), 312587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon GrColor4f::OpaqueWhite()); 313587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0], 314587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1], 315587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2], 316587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon input.fRGBA[3] * childColor.fRGBA[3]); 317587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 318587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 319587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon typedef GrFragmentProcessor INHERITED; 320f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 321f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (!fp) { 322f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return nullptr; 323f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 32406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return sk_sp<GrFragmentProcessor>(new PremulFragmentProcessor(std::move(fp))); 325f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon} 326f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 327f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////// 328f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 32906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentProcessor> fp, 3304cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman GrColor4f color) { 331f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon class ReplaceInputFragmentProcessor : public GrFragmentProcessor { 332f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 3334cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman ReplaceInputFragmentProcessor(sk_sp<GrFragmentProcessor> child, GrColor4f color) 334587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon : INHERITED(OptFlags(child.get(), color)), fColor(color) { 335f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->initClassID<ReplaceInputFragmentProcessor>(); 33606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman this->registerChildProcessor(std::move(child)); 337f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 338f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 339f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const char* name() const override { return "Replace Color"; } 340f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 34157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 34264c4728c70001ed074fecf5c4e083781987b12e9egdaniel class GLFP : public GrGLSLFragmentProcessor { 343f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 344f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GLFP() : fHaveSetColor(false) {} 345f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon void emitCode(EmitArgs& args) override { 346f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const char* colorName; 3475e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, 3485e58ceea8569f0d90ff7e3daf5de2def50407212cdalton kVec4f_GrSLType, 3495e58ceea8569f0d90ff7e3daf5de2def50407212cdalton kDefault_GrSLPrecision, 3505e58ceea8569f0d90ff7e3daf5de2def50407212cdalton "Color", &colorName); 351f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->emitChild(0, colorName, args); 352f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 353f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 354f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon private: 355018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void onSetData(const GrGLSLProgramDataManager& pdman, 356f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const GrProcessor& fp) override { 3574cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman GrColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor; 358f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (!fHaveSetColor || color != fPreviousColor) { 3594cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman pdman.set4fv(fColorUni, 1, color.fRGBA); 360f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon fPreviousColor = color; 361f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon fHaveSetColor = true; 362f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 363f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 364f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 365018fb62d12d1febf121fe265da5b6117b86a6541egdaniel GrGLSLProgramDataManager::UniformHandle fColorUni; 3664cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman bool fHaveSetColor; 3674cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman GrColor4f fPreviousColor; 368f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 369f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 370f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return new GLFP; 371f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 372f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 373f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon private: 374587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f color) { 375587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon OptimizationFlags childFlags = child->optimizationFlags(); 376587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon OptimizationFlags flags = kNone_OptimizationFlags; 377587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) { 378587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon flags |= kConstantOutputForConstantInput_OptimizationFlag; 379587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 380587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) { 381587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon flags |= kPreservesOpaqueInput_OptimizationFlag; 382587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 383587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return flags; 384587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 385587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 38694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override 38757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel {} 388f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 389f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon bool onIsEqual(const GrFragmentProcessor& that) const override { 390f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor; 391f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 392f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 393587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon GrColor4f constantOutputForConstantInput(GrColor4f) const override { 394587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return ConstantOutputForConstantInput(this->childProcessor(0), fColor); 395587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 396587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 3974cea3b9e9d9836c926a8feb55d050993d40b4b5ebrianosman GrColor4f fColor; 398587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 399587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon typedef GrFragmentProcessor INHERITED; 400f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 401f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 4025f13fbac19ee0ea9a3d5216740912d377a30d622Brian Salomon return sk_sp<GrFragmentProcessor>(new ReplaceInputFragmentProcessor(std::move(fp), color)); 403f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon} 404e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 40506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProcessor>* series, 406e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon int cnt) { 407e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon class SeriesFragmentProcessor : public GrFragmentProcessor { 408e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon public: 409587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt) 410587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon : INHERITED(OptFlags(children, cnt)) { 411e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SkASSERT(cnt > 1); 412e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->initClassID<SeriesFragmentProcessor>(); 413e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon for (int i = 0; i < cnt; ++i) { 41406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman this->registerChildProcessor(std::move(children[i])); 415e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 416e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 417e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 418e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon const char* name() const override { return "Series"; } 419e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 42057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 42164c4728c70001ed074fecf5c4e083781987b12e9egdaniel class GLFP : public GrGLSLFragmentProcessor { 422e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon public: 423e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon void emitCode(EmitArgs& args) override { 424ca9eeab0eaa32fc8f61be9003fafc3fe1afe78e4dvonbeck // First guy's input might be nil. 425ca9eeab0eaa32fc8f61be9003fafc3fe1afe78e4dvonbeck SkString temp("out0"); 426ca9eeab0eaa32fc8f61be9003fafc3fe1afe78e4dvonbeck this->emitChild(0, args.fInputColor, &temp, args); 427ca9eeab0eaa32fc8f61be9003fafc3fe1afe78e4dvonbeck SkString input = temp; 428ca9eeab0eaa32fc8f61be9003fafc3fe1afe78e4dvonbeck for (int i = 1; i < this->numChildProcessors() - 1; ++i) { 429e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon temp.printf("out%d", i); 430e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->emitChild(i, input.c_str(), &temp, args); 431e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon input = temp; 432e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 433e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon // Last guy writes to our output variable. 434e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->emitChild(this->numChildProcessors() - 1, input.c_str(), args); 435e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 436e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon }; 437e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return new GLFP; 438e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 439e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon private: 440587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon static OptimizationFlags OptFlags(sk_sp<GrFragmentProcessor>* children, int cnt) { 441587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon OptimizationFlags flags = kAll_OptimizationFlags; 442587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) { 443587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon flags &= children[i]->optimizationFlags(); 444587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 445587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return flags; 446587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 44794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 448e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 449e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 450e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 451587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon GrColor4f constantOutputForConstantInput(GrColor4f color) const override { 452587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon int childCnt = this->numChildProcessors(); 453587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon for (int i = 0; i < childCnt; ++i) { 454587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon color = ConstantOutputForConstantInput(this->childProcessor(i), color); 455587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 456587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon return color; 457587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon } 458587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon 459587e08f361ee3e775a6bbc6dca761dbba82e422cBrian Salomon typedef GrFragmentProcessor INHERITED; 460e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon }; 461e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 462e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon if (!cnt) { 463e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return nullptr; 464e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 465eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon if (1 == cnt) { 466eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon return series[0]; 467eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon } 468e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon // Run the through the series, do the invariant output processing, and look for eliminations. 469c0b642ca48d58416409e555549434066f09692b7Brian Salomon GrColorFragmentProcessorAnalysis info; 4700831f1b5f112f4e95532695dd701676f734cde54Brian Salomon info.analyzeProcessors(sk_sp_address_as_pointer_address(series), cnt); 47106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries; 472eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon GrColor4f knownColor; 473eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor); 474eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon if (leadingFPsToEliminate) { 475eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon sk_sp<GrFragmentProcessor> colorFP( 476eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::kIgnore_InputMode)); 477eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon if (leadingFPsToEliminate == cnt) { 478eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon return colorFP; 479eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon } 480eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon cnt = cnt - leadingFPsToEliminate + 1; 48106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman replacementSeries.reserve(cnt); 48206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman replacementSeries.emplace_back(std::move(colorFP)); 48306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman for (int i = 0; i < cnt - 1; ++i) { 484eec6f7be5461e588210f383b8af18f324a2bdb46Brian Salomon replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i])); 48506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman } 48606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman series = replacementSeries.begin(); 487e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 48806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return sk_sp<GrFragmentProcessor>(new SeriesFragmentProcessor(series, cnt)); 489e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon} 490a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon 491a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon////////////////////////////////////////////////////////////////////////////// 492a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon 493a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomonGrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) { 494a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) { 495a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon fFPStack.push_back(&pipeline.getFragmentProcessor(i)); 496a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon } 497a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon} 498a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon 499a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomonconst GrFragmentProcessor* GrFragmentProcessor::Iter::next() { 500a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon if (fFPStack.empty()) { 501a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon return nullptr; 502a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon } 503a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon const GrFragmentProcessor* back = fFPStack.back(); 504a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon fFPStack.pop_back(); 505a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon for (int i = back->numChildProcessors() - 1; i >= 0; --i) { 506a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon fFPStack.push_back(&back->childProcessor(i)); 507a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon } 508a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon return back; 509a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon} 510a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon 511