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