116a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel/*
216a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel * Copyright 2015 Google Inc.
316a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel *
416a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel * Use of this source code is governed by a BSD-style license that can be
516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel * found in the LICENSE file.
616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel */
716a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
816a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#include "SkArithmeticMode_gpu.h"
916a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
1016a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#if SK_SUPPORT_GPU
1116a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#include "GrContext.h"
1216a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#include "GrFragmentProcessor.h"
1316a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#include "GrInvariantOutput.h"
1416a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#include "GrProcessor.h"
1516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#include "GrTexture.h"
1664c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLFragmentProcessor.h"
172d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
18018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h"
197ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h"
20fa4cc8bf2aa782431609dd2ac16b1fc36de72e44egdaniel#include "glsl/GrGLSLXferProcessor.h"
2116a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
224ca2e6034365ad280ec64473f7f1d72ebd8335e4egdanielstatic void add_arithmetic_code(GrGLSLFragmentBuilder* fragBuilder,
23ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon                                const char* srcColor,
24f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel                                const char* dstColor,
25f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel                                const char* outputColor,
26f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel                                const char* kUni,
27f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel                                bool enforcePMColor) {
28f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    // We don't try to optimize for this case at all
29ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon    if (nullptr == srcColor) {
304ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppend("const vec4 src = vec4(1);");
31f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    } else {
324ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppendf("vec4 src = %s;", srcColor);
33f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    }
34f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
354ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("vec4 dst = %s;", dstColor);
364ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;",
374ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                             outputColor, kUni, kUni, kUni, kUni);
384ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel    fragBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
39d778febae6ee4de8f0519c6b9e131b6584a265cfreed    if (enforcePMColor) {
404ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        fragBuilder->codeAppendf("%s.rgb = min(%s.rgb, %s.a);",
414ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                 outputColor, outputColor, outputColor);
42f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    }
43f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel}
44f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
4564c4728c70001ed074fecf5c4e083781987b12e9egdanielclass GLArithmeticFP : public GrGLSLFragmentProcessor {
4616a04b84147867b62f92969ac8f4f4a9ab009aeaegdanielpublic:
477c157a988845fb00f9024d6db6dda142c3458033wangyix    void emitCode(EmitArgs& args) override {
489cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips        const GrArithmeticFP& arith = args.fFp.cast<GrArithmeticFP>();
499cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips
508528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
5138ddbadd00d60576f29d2ca33316b4626c9b0470bsalomon        SkString dstColor("dstColor");
5238ddbadd00d60576f29d2ca33316b4626c9b0470bsalomon        this->emitChild(0, nullptr, &dstColor, args);
53f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
545e58ceea8569f0d90ff7e3daf5de2def50407212cdalton        fKUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
557ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                 kVec4f_GrSLType, kDefault_GrSLPrecision,
567ea439b2203855db97330b25945b87dd4b170b8begdaniel                                                 "k");
577ea439b2203855db97330b25945b87dd4b170b8begdaniel        const char* kUni = args.fUniformHandler->getUniformCStr(fKUni);
58f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
594ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        add_arithmetic_code(fragBuilder,
604ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                            args.fInputColor,
614ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                            dstColor.c_str(),
624ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                            args.fOutputColor,
634ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                            kUni,
649cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips                            arith.enforcePMColor());
65f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    }
6616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
67bf536af15f4c176d3bef65b77b7592718bfd9068robertphillips    static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
68f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel        const GrArithmeticFP& arith = proc.cast<GrArithmeticFP>();
69f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel        uint32_t key = arith.enforcePMColor() ? 1 : 0;
70f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel        b->add32(key);
71f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    }
7216a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
73b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyixprotected:
74018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
75b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix        const GrArithmeticFP& arith = proc.cast<GrArithmeticFP>();
76b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix        pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
77b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix    }
78b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix
7916a04b84147867b62f92969ac8f4f4a9ab009aeaegdanielprivate:
80018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    GrGLSLProgramDataManager::UniformHandle fKUni;
8116a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
8264c4728c70001ed074fecf5c4e083781987b12e9egdaniel    typedef GrGLSLFragmentProcessor INHERITED;
8316a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel};
8416a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
8516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel///////////////////////////////////////////////////////////////////////////////
8616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
874a339529612a43871d021877e58698e067d6c4cdbsalomonGrArithmeticFP::GrArithmeticFP(float k1, float k2, float k3, float k4, bool enforcePMColor,
884a339529612a43871d021877e58698e067d6c4cdbsalomon                               const GrFragmentProcessor* dst)
8916a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel  : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fEnforcePMColor(enforcePMColor) {
9016a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    this->initClassID<GrArithmeticFP>();
91f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
92ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon    SkASSERT(dst);
93ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon    SkDEBUGCODE(int dstIndex = )this->registerChildProcessor(dst);
94ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon    SkASSERT(0 == dstIndex);
9516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
9616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
9757d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielvoid GrArithmeticFP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
9816a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    GLArithmeticFP::GenKey(*this, caps, b);
9916a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
10016a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
10157d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLFragmentProcessor* GrArithmeticFP::onCreateGLSLInstance() const {
1029cdb9920fcad286ecf7875ea19902022b644fbdcrobertphillips    return new GLArithmeticFP;
10316a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
10416a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
10516a04b84147867b62f92969ac8f4f4a9ab009aeaegdanielbool GrArithmeticFP::onIsEqual(const GrFragmentProcessor& fpBase) const {
10616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    const GrArithmeticFP& fp = fpBase.cast<GrArithmeticFP>();
10716a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    return fK1 == fp.fK1 &&
10816a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel           fK2 == fp.fK2 &&
10916a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel           fK3 == fp.fK3 &&
11016a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel           fK4 == fp.fK4 &&
11116a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel           fEnforcePMColor == fp.fEnforcePMColor;
11216a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
11316a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
11416a04b84147867b62f92969ac8f4f4a9ab009aeaegdanielvoid GrArithmeticFP::onComputeInvariantOutput(GrInvariantOutput* inout) const {
11516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    // TODO: optimize this
11616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
11716a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
11816a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
11916a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel///////////////////////////////////////////////////////////////////////////////
12016a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
121c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrFragmentProcessor* GrArithmeticFP::TestCreate(GrProcessorTestData* d) {
1220067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k1 = d->fRandom->nextF();
1230067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k2 = d->fRandom->nextF();
1240067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k3 = d->fRandom->nextF();
1250067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k4 = d->fRandom->nextF();
1260067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    bool enforcePMColor = d->fRandom->nextBool();
1270067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt
128ae4738f677c70f4ec7687422e1510ee3d80d810ebsalomon    SkAutoTUnref<const GrFragmentProcessor> dst(GrProcessorUnitTest::CreateChildFP(d));
1294a339529612a43871d021877e58698e067d6c4cdbsalomon    return new GrArithmeticFP(k1, k2, k3, k4, enforcePMColor, dst);
13016a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
13116a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
132f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdanielGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrArithmeticFP);
13316a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
134f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel///////////////////////////////////////////////////////////////////////////////
135f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel// Xfer Processor
136f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel///////////////////////////////////////////////////////////////////////////////
13716a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
13841d4f09356567ead0216e1a7e4110bd58822b81fegdanielclass ArithmeticXP : public GrXferProcessor {
13941d4f09356567ead0216e1a7e4110bd58822b81fegdanielpublic:
14086ae0a9e465f157eaa263ef7515e10619946ff83cdalton    ArithmeticXP(const DstTexture*, bool hasMixedSamples,
14186ae0a9e465f157eaa263ef7515e10619946ff83cdalton                 float k1, float k2, float k3, float k4, bool enforcePMColor);
14241d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
14336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "Arithmetic"; }
14441d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
14557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    GrGLSLXferProcessor* createGLSLInstance() const override;
14641d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
14741d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    float k1() const { return fK1; }
14841d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    float k2() const { return fK2; }
14941d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    float k3() const { return fK3; }
15041d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    float k4() const { return fK4; }
15141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    bool enforcePMColor() const { return fEnforcePMColor; }
15241d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
15341d4f09356567ead0216e1a7e4110bd58822b81fegdanielprivate:
154de4166a3b45d859512e27e3257841f064d67549cethannicholas    GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations& optimizations,
155c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel                                                 bool doesStencilWrite,
156c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel                                                 GrColor* overrideColor,
15756cf6dcb6572f1d355af041c1ebf157b2b3d0165egdaniel                                                 const GrCaps& caps) const override;
158c19cdc254cc08f334b00c3b9fdb703818c8ca681egdaniel
15957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
16041d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
16136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onIsEqual(const GrXferProcessor& xpBase) const override {
16241d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        const ArithmeticXP& xp = xpBase.cast<ArithmeticXP>();
16341d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        if (fK1 != xp.fK1 ||
16441d4f09356567ead0216e1a7e4110bd58822b81fegdaniel            fK2 != xp.fK2 ||
16541d4f09356567ead0216e1a7e4110bd58822b81fegdaniel            fK3 != xp.fK3 ||
16641d4f09356567ead0216e1a7e4110bd58822b81fegdaniel            fK4 != xp.fK4 ||
16741d4f09356567ead0216e1a7e4110bd58822b81fegdaniel            fEnforcePMColor != xp.fEnforcePMColor) {
16841d4f09356567ead0216e1a7e4110bd58822b81fegdaniel            return false;
16941d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        }
17041d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        return true;
17141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    }
17241d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
17341d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    float                       fK1, fK2, fK3, fK4;
17441d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    bool                        fEnforcePMColor;
17541d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
17641d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    typedef GrXferProcessor INHERITED;
17741d4f09356567ead0216e1a7e4110bd58822b81fegdaniel};
17841d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
17941d4f09356567ead0216e1a7e4110bd58822b81fegdaniel///////////////////////////////////////////////////////////////////////////////
18041d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
181fa4cc8bf2aa782431609dd2ac16b1fc36de72e44egdanielclass GLArithmeticXP : public GrGLSLXferProcessor {
182f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdanielpublic:
183af96fce87937aba4aa5d394ee6316ba790308490ericrk    GLArithmeticXP(const ArithmeticXP& arithmeticXP)
184af96fce87937aba4aa5d394ee6316ba790308490ericrk        : fEnforcePMColor(arithmeticXP.enforcePMColor()) {
18516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    }
18616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
18736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    ~GLArithmeticXP() override {}
188f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
189cfc18867d982119d9dc2888bf09f1093012daaddjvanverth    static void GenKey(const GrProcessor& processor, const GrGLSLCaps& caps,
19050785a3d10b53bea5beb6e18431a2449860be237bsalomon                       GrProcessorKeyBuilder* b) {
19141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        const ArithmeticXP& arith = processor.cast<ArithmeticXP>();
19250785a3d10b53bea5beb6e18431a2449860be237bsalomon        uint32_t key = arith.enforcePMColor() ? 1 : 0;
19350785a3d10b53bea5beb6e18431a2449860be237bsalomon        b->add32(key);
19450785a3d10b53bea5beb6e18431a2449860be237bsalomon    }
19550785a3d10b53bea5beb6e18431a2449860be237bsalomon
19650785a3d10b53bea5beb6e18431a2449860be237bsalomonprivate:
1977ea439b2203855db97330b25945b87dd4b170b8begdaniel    void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder* fragBuilder,
1987ea439b2203855db97330b25945b87dd4b170b8begdaniel                                 GrGLSLUniformHandler* uniformHandler,
1994ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                 const char* srcColor,
200f34b293681ea49aaa4aaa70d84515e4a58a112e7egdaniel                                 const char* srcCoverage,
2014ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                 const char* dstColor,
2024ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                 const char* outColor,
203f34b293681ea49aaa4aaa70d84515e4a58a112e7egdaniel                                 const char* outColorSecondary,
2044ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                 const GrXferProcessor& proc) override {
2055e58ceea8569f0d90ff7e3daf5de2def50407212cdalton        fKUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
2067ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           kVec4f_GrSLType, kDefault_GrSLPrecision,
2077ea439b2203855db97330b25945b87dd4b170b8begdaniel                                           "k");
2087ea439b2203855db97330b25945b87dd4b170b8begdaniel        const char* kUni = uniformHandler->getUniformCStr(fKUni);
209f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
2104ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel        add_arithmetic_code(fragBuilder, srcColor, dstColor, outColor, kUni, fEnforcePMColor);
211f34b293681ea49aaa4aaa70d84515e4a58a112e7egdaniel
212f34b293681ea49aaa4aaa70d84515e4a58a112e7egdaniel        // Apply coverage.
213f42fca4027ed4f235ef927786813a5ed0e6652b9robertphillips        INHERITED::DefaultCoverageModulation(fragBuilder, srcCoverage, dstColor, outColor,
214f42fca4027ed4f235ef927786813a5ed0e6652b9robertphillips                                             outColorSecondary, proc);
21516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel    }
21616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
217018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    void onSetData(const GrGLSLProgramDataManager& pdman,
21836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein                   const GrXferProcessor& processor) override {
21941d4f09356567ead0216e1a7e4110bd58822b81fegdaniel        const ArithmeticXP& arith = processor.cast<ArithmeticXP>();
220f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel        pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
221f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel        fEnforcePMColor = arith.enforcePMColor();
222f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    };
223f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
224018fb62d12d1febf121fe265da5b6117b86a6541egdaniel    GrGLSLProgramDataManager::UniformHandle fKUni;
225f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    bool fEnforcePMColor;
226f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
227fa4cc8bf2aa782431609dd2ac16b1fc36de72e44egdaniel    typedef GrGLSLXferProcessor INHERITED;
228f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel};
229f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
230f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel///////////////////////////////////////////////////////////////////////////////
231f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
23286ae0a9e465f157eaa263ef7515e10619946ff83cdaltonArithmeticXP::ArithmeticXP(const DstTexture* dstTexture, bool hasMixedSamples,
23386ae0a9e465f157eaa263ef7515e10619946ff83cdalton                           float k1, float k2, float k3, float k4, bool enforcePMColor)
23486ae0a9e465f157eaa263ef7515e10619946ff83cdalton    : INHERITED(dstTexture, true, hasMixedSamples)
23550785a3d10b53bea5beb6e18431a2449860be237bsalomon    , fK1(k1)
236f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    , fK2(k2)
237f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    , fK3(k3)
238f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    , fK4(k4)
239f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    , fEnforcePMColor(enforcePMColor) {
24041d4f09356567ead0216e1a7e4110bd58822b81fegdaniel    this->initClassID<ArithmeticXP>();
24116a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
24216a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
24357d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielvoid ArithmeticXP::onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
244f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    GLArithmeticXP::GenKey(*this, caps, b);
24516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
24616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
24757d3b039c635945e1dc2fcbac3462ed8bfedb068egdanielGrGLSLXferProcessor* ArithmeticXP::createGLSLInstance() const { return new GLArithmeticXP(*this); }
24816a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
249de4166a3b45d859512e27e3257841f064d67549cethannicholasGrXferProcessor::OptFlags ArithmeticXP::onGetOptimizations(
250de4166a3b45d859512e27e3257841f064d67549cethannicholas                                                       const GrPipelineOptimizations& optimizations,
251de4166a3b45d859512e27e3257841f064d67549cethannicholas                                                       bool doesStencilWrite,
252de4166a3b45d859512e27e3257841f064d67549cethannicholas                                                       GrColor* overrideColor,
25356cf6dcb6572f1d355af041c1ebf157b2b3d0165egdaniel                                                       const GrCaps& caps) const {
2547765a477ee3ca5e2c6ada1e16c31dfaae2079240bsalomon   return GrXferProcessor::kNone_OptFlags;
255f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel}
25616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
257f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel///////////////////////////////////////////////////////////////////////////////
258f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
259f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdanielGrArithmeticXPFactory::GrArithmeticXPFactory(float k1, float k2, float k3, float k4,
260af96fce87937aba4aa5d394ee6316ba790308490ericrk                                             bool enforcePMColor)
261f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fEnforcePMColor(enforcePMColor) {
26254f0e9d784122cfd3f5968e0fea971d5b5a4805aegdaniel    this->initClassID<GrArithmeticXPFactory>();
26316a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel}
26416a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
26541d4f09356567ead0216e1a7e4110bd58822b81fegdanielGrXferProcessor*
2664b91f768b348aa1cebeb54f3ff9331938734c242bsalomonGrArithmeticXPFactory::onCreateXferProcessor(const GrCaps& caps,
267de4166a3b45d859512e27e3257841f064d67549cethannicholas                                             const GrPipelineOptimizations& optimizations,
26886ae0a9e465f157eaa263ef7515e10619946ff83cdalton                                             bool hasMixedSamples,
2696a44c6a7d89b748fb040d41697a337d357d7fa22bsalomon                                             const DstTexture* dstTexture) const {
270385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new ArithmeticXP(dstTexture, hasMixedSamples, fK1, fK2, fK3, fK4, fEnforcePMColor);
27141d4f09356567ead0216e1a7e4110bd58822b81fegdaniel}
27241d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
27341d4f09356567ead0216e1a7e4110bd58822b81fegdaniel
2741fa4572d1a32e9fbf102d7388efe5e44bef460f1cdaltonvoid GrArithmeticXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
2751fa4572d1a32e9fbf102d7388efe5e44bef460f1cdalton                                                     InvariantBlendedColor* blendedColor) const {
2761fa4572d1a32e9fbf102d7388efe5e44bef460f1cdalton    blendedColor->fWillBlendWithDst = true;
2771fa4572d1a32e9fbf102d7388efe5e44bef460f1cdalton
2781fa4572d1a32e9fbf102d7388efe5e44bef460f1cdalton    // TODO: We could try to optimize this more. For example if fK1 and fK3 are zero, then we won't
2791fa4572d1a32e9fbf102d7388efe5e44bef460f1cdalton    // be blending the color with dst at all so we can know what the output color is (up to the
2801fa4572d1a32e9fbf102d7388efe5e44bef460f1cdalton    // valid color components passed in).
2811fa4572d1a32e9fbf102d7388efe5e44bef460f1cdalton    blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
282f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel}
283f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
284f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdanielGR_DEFINE_XP_FACTORY_TEST(GrArithmeticXPFactory);
285f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
286c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonconst GrXPFactory* GrArithmeticXPFactory::TestCreate(GrProcessorTestData* d) {
2870067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k1 = d->fRandom->nextF();
2880067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k2 = d->fRandom->nextF();
2890067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k3 = d->fRandom->nextF();
2900067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    float k4 = d->fRandom->nextF();
2910067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    bool enforcePMColor = d->fRandom->nextBool();
292f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel
293f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel    return GrArithmeticXPFactory::Create(k1, k2, k3, k4, enforcePMColor);
294f351aa3bf1b1d7639be8e1e6a35137b89a8dd93degdaniel}
29516a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel
29616a04b84147867b62f92969ac8f4f4a9ab009aeaegdaniel#endif
297