1bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 2bf87730c7da80616f6ea17765290dbd2c147a669bsalomon/* 3bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* Copyright 2015 Google Inc. 4bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* 5bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* Use of this source code is governed by a BSD-style license that can be 6bf87730c7da80616f6ea17765290dbd2c147a669bsalomon* found in the LICENSE file. 7bf87730c7da80616f6ea17765290dbd2c147a669bsalomon*/ 8bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 9bf87730c7da80616f6ea17765290dbd2c147a669bsalomon#include "GrFragmentProcessor.h" 10bf87730c7da80616f6ea17765290dbd2c147a669bsalomon#include "GrCoordTransform.h" 117ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "GrInvariantOutput.h" 127ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "GrProcOptInfo.h" 1364c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h" 142d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h" 15018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h" 167ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h" 17e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#include "effects/GrConstColorProcessor.h" 18bf87730c7da80616f6ea17765290dbd2c147a669bsalomon#include "effects/GrXfermodeFragmentProcessor.h" 19bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 20bf87730c7da80616f6ea17765290dbd2c147a669bsalomonGrFragmentProcessor::~GrFragmentProcessor() { 21bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // If we got here then our ref count must have reached zero, so we will have converted refs 22bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // to pending executions for all children. 23bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < fChildProcessors.count(); ++i) { 24bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fChildProcessors[i]->completedExecution(); 25bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 26bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 27bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 28bf87730c7da80616f6ea17765290dbd2c147a669bsalomonbool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that, 29bf87730c7da80616f6ea17765290dbd2c147a669bsalomon bool ignoreCoordTransforms) const { 30bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (this->classID() != that.classID() || 31bf87730c7da80616f6ea17765290dbd2c147a669bsalomon !this->hasSameTextureAccesses(that)) { 32bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 33bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 34bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (ignoreCoordTransforms) { 35bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (this->numTransforms() != that.numTransforms()) { 36bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 37bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 38bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } else if (!this->hasSameTransforms(that)) { 39bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 40bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 41bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (!this->onIsEqual(that)) { 42bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 43bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 44bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (this->numChildProcessors() != that.numChildProcessors()) { 45bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 46bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 47bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < this->numChildProcessors(); ++i) { 48bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (!this->childProcessor(i).isEqual(that.childProcessor(i), ignoreCoordTransforms)) { 49bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 50bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 51bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 52bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return true; 53bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 54bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 5557d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const { 5657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance(); 57bf87730c7da80616f6ea17765290dbd2c147a669bsalomon glFragProc->fChildProcessors.push_back_n(fChildProcessors.count()); 58bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < fChildProcessors.count(); ++i) { 5957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance(); 60bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 61bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return glFragProc; 62bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 63bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 64bf87730c7da80616f6ea17765290dbd2c147a669bsalomonvoid GrFragmentProcessor::addTextureAccess(const GrTextureAccess* textureAccess) { 65bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // Can't add texture accesses after registering any children since their texture accesses have 66bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // already been bubbled up into our fTextureAccesses array 67bf87730c7da80616f6ea17765290dbd2c147a669bsalomon SkASSERT(fChildProcessors.empty()); 68bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 69bf87730c7da80616f6ea17765290dbd2c147a669bsalomon INHERITED::addTextureAccess(textureAccess); 70bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fNumTexturesExclChildren++; 71bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 72bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 73bf87730c7da80616f6ea17765290dbd2c147a669bsalomonvoid GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { 74bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // Can't add transforms after registering any children since their transforms have already been 75bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // bubbled up into our fCoordTransforms array 76bf87730c7da80616f6ea17765290dbd2c147a669bsalomon SkASSERT(fChildProcessors.empty()); 77bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 78bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fCoordTransforms.push_back(transform); 79bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_GrCoordSet; 80bf87730c7da80616f6ea17765290dbd2c147a669bsalomon SkDEBUGCODE(transform->setInProcessor();) 81bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fNumTransformsExclChildren++; 82bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 83bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 84bf87730c7da80616f6ea17765290dbd2c147a669bsalomonint GrFragmentProcessor::registerChildProcessor(const GrFragmentProcessor* child) { 85bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // Append the child's transforms to our transforms array and the child's textures array to our 86bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // textures array 87bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (!child->fCoordTransforms.empty()) { 88bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fCoordTransforms.push_back_n(child->fCoordTransforms.count(), 89bf87730c7da80616f6ea17765290dbd2c147a669bsalomon child->fCoordTransforms.begin()); 90bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 91bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (!child->fTextureAccesses.empty()) { 92bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fTextureAccesses.push_back_n(child->fTextureAccesses.count(), 93bf87730c7da80616f6ea17765290dbd2c147a669bsalomon child->fTextureAccesses.begin()); 94bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 95bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 96bf87730c7da80616f6ea17765290dbd2c147a669bsalomon int index = fChildProcessors.count(); 97bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fChildProcessors.push_back(SkRef(child)); 98bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 99bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (child->willReadFragmentPosition()) { 100bf87730c7da80616f6ea17765290dbd2c147a669bsalomon this->setWillReadFragmentPosition(); 101bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 102bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 103bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (child->usesLocalCoords()) { 104bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fUsesLocalCoords = true; 105bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 106bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 107bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return index; 108bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 109bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 110bf87730c7da80616f6ea17765290dbd2c147a669bsalomonvoid GrFragmentProcessor::notifyRefCntIsZero() const { 111bf87730c7da80616f6ea17765290dbd2c147a669bsalomon // See comment above GrProgramElement for a detailed explanation of why we do this. 112bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < fChildProcessors.count(); ++i) { 113bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fChildProcessors[i]->addPendingExecution(); 114bf87730c7da80616f6ea17765290dbd2c147a669bsalomon fChildProcessors[i]->unref(); 115bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 116bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 117bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 118bf87730c7da80616f6ea17765290dbd2c147a669bsalomonbool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { 119bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (this->numTransforms() != that.numTransforms()) { 120bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 121bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 122bf87730c7da80616f6ea17765290dbd2c147a669bsalomon int count = this->numTransforms(); 123bf87730c7da80616f6ea17765290dbd2c147a669bsalomon for (int i = 0; i < count; ++i) { 124bf87730c7da80616f6ea17765290dbd2c147a669bsalomon if (this->coordTransform(i) != that.coordTransform(i)) { 125bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return false; 126bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 127bf87730c7da80616f6ea17765290dbd2c147a669bsalomon } 128bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return true; 129bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 130bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 131f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonconst GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputAlpha( 132bf87730c7da80616f6ea17765290dbd2c147a669bsalomon const GrFragmentProcessor* fp) { 133f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (!fp) { 134f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return nullptr; 135f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 136bf87730c7da80616f6ea17765290dbd2c147a669bsalomon return GrXfermodeFragmentProcessor::CreateFromDstProcessor(fp, SkXfermode::kDstIn_Mode); 137bf87730c7da80616f6ea17765290dbd2c147a669bsalomon} 138bf87730c7da80616f6ea17765290dbd2c147a669bsalomon 139f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonconst GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputUnpremulColor( 140f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const GrFragmentProcessor* fp) { 141f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 142f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon class PremulFragmentProcessor : public GrFragmentProcessor { 143f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 144f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon PremulFragmentProcessor(const GrFragmentProcessor* processor) { 145f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->initClassID<PremulFragmentProcessor>(); 146f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->registerChildProcessor(processor); 147f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 148f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 149f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const char* name() const override { return "Premultiply"; } 150f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 151f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon private: 15257d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 15364c4728c70001ed074fecf5c4e083781987b12e9egdaniel class GLFP : public GrGLSLFragmentProcessor { 154f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 155f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon void emitCode(EmitArgs& args) override { 1568528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 157f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->emitChild(0, nullptr, args); 1584ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor, 159f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon args.fInputColor); 1604ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor); 161f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 162f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 163f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return new GLFP; 164f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 165f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 16657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override {} 167f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 168f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 169f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 170f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 171f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon // TODO: Add a helper to GrInvariantOutput that handles multiplying by color with flags? 172f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (!(inout->validFlags() & kA_GrColorComponentFlag)) { 173f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); 174f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return; 175f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 176f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 177f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrInvariantOutput childOutput(GrColor_WHITE, kRGBA_GrColorComponentFlags, false); 178f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->childProcessor(0).computeInvariantOutput(&childOutput); 179f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 180f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (0 == GrColorUnpackA(inout->color()) || 0 == GrColorUnpackA(childOutput.color())) { 181f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon inout->mulByKnownFourComponents(0x0); 182f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return; 183f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 184f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColorComponentFlags commonFlags = childOutput.validFlags() & inout->validFlags(); 185f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor c0 = GrPremulColor(inout->color()); 186f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor c1 = childOutput.color(); 187f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor color = 0x0; 188f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (commonFlags & kR_GrColorComponentFlag) { 189f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon color |= SkMulDiv255Round(GrColorUnpackR(c0), GrColorUnpackR(c1)) << 190f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor_SHIFT_R; 191f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 192f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (commonFlags & kG_GrColorComponentFlag) { 193f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon color |= SkMulDiv255Round(GrColorUnpackG(c0), GrColorUnpackG(c1)) << 194f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor_SHIFT_G; 195f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 196f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (commonFlags & kB_GrColorComponentFlag) { 197f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon color |= SkMulDiv255Round(GrColorUnpackB(c0), GrColorUnpackB(c1)) << 198f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor_SHIFT_B; 199f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 200f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon inout->setToOther(commonFlags, color, GrInvariantOutput::kWill_ReadInput); 201f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 202f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 203f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (!fp) { 204f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return nullptr; 205f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 206f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return new PremulFragmentProcessor(fp); 207f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon} 208f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 209f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon////////////////////////////////////////////////////////////////////////////// 210f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 211f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomonconst GrFragmentProcessor* GrFragmentProcessor::OverrideInput(const GrFragmentProcessor* fp, 212f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor color) { 213f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon class ReplaceInputFragmentProcessor : public GrFragmentProcessor { 214f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 215f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon ReplaceInputFragmentProcessor(const GrFragmentProcessor* child, GrColor color) 216f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon : fColor(color) { 217f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->initClassID<ReplaceInputFragmentProcessor>(); 218f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->registerChildProcessor(child); 219f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 220f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 221f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const char* name() const override { return "Replace Color"; } 222f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 22357d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 22464c4728c70001ed074fecf5c4e083781987b12e9egdaniel class GLFP : public GrGLSLFragmentProcessor { 225f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon public: 226f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GLFP() : fHaveSetColor(false) {} 227f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon void emitCode(EmitArgs& args) override { 228f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const char* colorName; 2295e58ceea8569f0d90ff7e3daf5de2def50407212cdalton fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, 2305e58ceea8569f0d90ff7e3daf5de2def50407212cdalton kVec4f_GrSLType, 2315e58ceea8569f0d90ff7e3daf5de2def50407212cdalton kDefault_GrSLPrecision, 2325e58ceea8569f0d90ff7e3daf5de2def50407212cdalton "Color", &colorName); 233f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->emitChild(0, colorName, args); 234f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 235f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 236f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon private: 237018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void onSetData(const GrGLSLProgramDataManager& pdman, 238f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon const GrProcessor& fp) override { 239f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor color = fp.cast<ReplaceInputFragmentProcessor>().fColor; 240f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (!fHaveSetColor || color != fPreviousColor) { 241018fb62d12d1febf121fe265da5b6117b86a6541egdaniel static const float scale = 1.f / 255.f; 242018fb62d12d1febf121fe265da5b6117b86a6541egdaniel float floatColor[4] = { 243f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColorUnpackR(color) * scale, 244f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColorUnpackG(color) * scale, 245f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColorUnpackB(color) * scale, 246f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColorUnpackA(color) * scale, 247f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 248f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon pdman.set4fv(fColorUni, 1, floatColor); 249f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon fPreviousColor = color; 250f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon fHaveSetColor = true; 251f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 252f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 253f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 254018fb62d12d1febf121fe265da5b6117b86a6541egdaniel GrGLSLProgramDataManager::UniformHandle fColorUni; 255f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon bool fHaveSetColor; 256f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor fPreviousColor; 257f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 258f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 259f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return new GLFP; 260f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 261f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 262f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon private: 26357d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override 26457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel {} 265f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 266f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon bool onIsEqual(const GrFragmentProcessor& that) const override { 267f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor; 268f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 269f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 270f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 271f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon inout->setToOther(kRGBA_GrColorComponentFlags, fColor, 272f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrInvariantOutput::kWillNot_ReadInput); 273f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon this->childProcessor(0).computeInvariantOutput(inout); 274f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 275f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 276f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrColor fColor; 277f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon }; 278f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 279f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags, false); 280f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon fp->computeInvariantOutput(&childOut); 281f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon if (childOut.willUseInputColor()) { 282f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return new ReplaceInputFragmentProcessor(fp, color); 283f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } else { 284f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon return SkRef(fp); 285f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon } 286f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon} 287e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 288e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomonconst GrFragmentProcessor* GrFragmentProcessor::RunInSeries(const GrFragmentProcessor* series[], 289e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon int cnt) { 290e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon class SeriesFragmentProcessor : public GrFragmentProcessor { 291e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon public: 292e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SeriesFragmentProcessor(const GrFragmentProcessor* children[], int cnt){ 293e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SkASSERT(cnt > 1); 294e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->initClassID<SeriesFragmentProcessor>(); 295e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon for (int i = 0; i < cnt; ++i) { 296e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->registerChildProcessor(children[i]); 297e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 298e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 299e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 300e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon const char* name() const override { return "Series"; } 301e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 30257d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 30364c4728c70001ed074fecf5c4e083781987b12e9egdaniel class GLFP : public GrGLSLFragmentProcessor { 304e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon public: 305e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon void emitCode(EmitArgs& args) override { 306e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SkString input(args.fInputColor); 307e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon for (int i = 0; i < this->numChildProcessors() - 1; ++i) { 308e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SkString temp; 309e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon temp.printf("out%d", i); 310e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->emitChild(i, input.c_str(), &temp, args); 311e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon input = temp; 312e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 313e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon // Last guy writes to our output variable. 314e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->emitChild(this->numChildProcessors() - 1, input.c_str(), args); 315e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 316e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon }; 317e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return new GLFP; 318e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 319e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 320e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon private: 32157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override {} 322e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 323e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon bool onIsEqual(const GrFragmentProcessor&) const override { return true; } 324e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 325e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 326e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon GrProcOptInfo info; 327e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SkTDArray<const GrFragmentProcessor*> children; 328e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon children.setCount(this->numChildProcessors()); 329e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon for (int i = 0; i < children.count(); ++i) { 330e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon children[i] = &this->childProcessor(i); 331e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 332e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon info.calcWithInitialValues(children.begin(), children.count(), inout->color(), 333e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon inout->validFlags(), false, false); 334e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon for (int i = 0; i < this->numChildProcessors(); ++i) { 335e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon this->childProcessor(i).computeInvariantOutput(inout); 336e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 337e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 338e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon }; 339e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 340e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon if (!cnt) { 341e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return nullptr; 342e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 343e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 344e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon // Run the through the series, do the invariant output processing, and look for eliminations. 345e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SkTDArray<const GrFragmentProcessor*> replacementSeries; 346e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon SkAutoTUnref<const GrFragmentProcessor> colorFP; 347e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon GrProcOptInfo info; 348e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 349e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon info.calcWithInitialValues(series, cnt, 0x0, kNone_GrColorComponentFlags, false, false); 350e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon if (kRGBA_GrColorComponentFlags == info.validFlags()) { 351e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return GrConstColorProcessor::Create(info.color(), 352e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon GrConstColorProcessor::kIgnore_InputMode); 353e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } else { 354e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon int firstIdx = info.firstEffectiveProcessorIndex(); 355e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon cnt -= firstIdx; 356e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon if (firstIdx > 0 && info.inputColorIsUsed()) { 357e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon colorFP.reset(GrConstColorProcessor::Create(info.inputColorToFirstEffectiveProccesor(), 358e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon GrConstColorProcessor::kIgnore_InputMode)); 359e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon cnt += 1; 360e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon replacementSeries.setCount(cnt); 361e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon replacementSeries[0] = colorFP; 362e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon for (int i = 0; i < cnt - 1; ++i) { 363e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon replacementSeries[i + 1] = series[firstIdx + i]; 364e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 365e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon series = replacementSeries.begin(); 366e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } else { 367e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon series += firstIdx; 368e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon cnt -= firstIdx; 369e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 370e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 371e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 372e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon if (1 == cnt) { 373e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return SkRef(series[0]); 374e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } else { 375e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return new SeriesFragmentProcessor(series, cnt); 376e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 377e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon} 378e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 379