14973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt/*
24973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt * Copyright 2014 Google Inc.
34973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt *
44973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt * Use of this source code is governed by a BSD-style license that can be
54973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt * found in the LICENSE file.
64973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt */
74973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
84973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt#include "GrDefaultGeoProcFactory.h"
94973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
1006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman#include "SkRefCnt.h"
11fa6d865215b48fac4ee24c120736e500d418f641Brian Osman#include "glsl/GrGLSLColorSpaceXformHelper.h"
122d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h"
13e659a581f63fdccb64dce2dc8a478cf56831feeaegdaniel#include "glsl/GrGLSLGeometryProcessor.h"
142d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLVertexShaderBuilder.h"
150eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel#include "glsl/GrGLSLVarying.h"
167ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h"
1764c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLUtil.h"
184973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
194973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt/*
204973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt * The default Geometry Processor simply takes position and multiplies it by the uniform view
214973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt * matrix. It also leaves coverage untouched.  Behind the scenes, we may add per vertex color or
224973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt * local coords.
234973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt */
24b2aa7cb90f4c66125056bac70dbca2093dd5ba41joshualitt
25b2aa7cb90f4c66125056bac70dbca2093dd5ba41joshualittenum GPFlag {
263de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    kColorAttribute_GPFlag          = 0x1,
273de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    kColorAttributeIsSkColor_GPFlag = 0x2,
283de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    kLocalCoordAttribute_GPFlag     = 0x4,
293de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    kCoverageAttribute_GPFlag       = 0x8,
30fa6d865215b48fac4ee24c120736e500d418f641Brian Osman
31fa6d865215b48fac4ee24c120736e500d418f641Brian Osman    kLinearizeColorAttribute_GPFlag = 0x10,
32b2aa7cb90f4c66125056bac70dbca2093dd5ba41joshualitt};
33b2aa7cb90f4c66125056bac70dbca2093dd5ba41joshualitt
344973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualittclass DefaultGeoProc : public GrGeometryProcessor {
354973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualittpublic:
3606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    static sk_sp<GrGeometryProcessor> Make(uint32_t gpTypeFlags,
373de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                                           GrColor color,
38fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                           sk_sp<GrColorSpaceXform> colorSpaceXform,
393de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                                           const SkMatrix& viewMatrix,
403de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                                           const SkMatrix& localMatrix,
413de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                                           bool localCoordsWillBeRead,
423de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                                           uint8_t coverage) {
4306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        return sk_sp<GrGeometryProcessor>(new DefaultGeoProc(
44fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                gpTypeFlags, color, std::move(colorSpaceXform), viewMatrix, localMatrix, coverage,
45fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                localCoordsWillBeRead));
464973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt    }
474973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
4836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "DefaultGeometryProcessor"; }
494973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
5071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    const Attribute* inPosition() const { return fInPosition; }
5171c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    const Attribute* inColor() const { return fInColor; }
5271c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    const Attribute* inLocalCoords() const { return fInLocalCoords; }
5371c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt    const Attribute* inCoverage() const { return fInCoverage; }
5488c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt    GrColor color() const { return fColor; }
55b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt    bool hasVertexColor() const { return SkToBool(fInColor); }
56e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt    const SkMatrix& viewMatrix() const { return fViewMatrix; }
57e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt    const SkMatrix& localMatrix() const { return fLocalMatrix; }
587765a477ee3ca5e2c6ada1e16c31dfaae2079240bsalomon    bool localCoordsWillBeRead() const { return fLocalCoordsWillBeRead; }
599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    uint8_t coverage() const { return fCoverage; }
60b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt    bool hasVertexCoverage() const { return SkToBool(fInCoverage); }
61fa6d865215b48fac4ee24c120736e500d418f641Brian Osman    bool linearizeColor() const {
62fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        // Linearization should only happen with SkColor
63fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        bool linearize = SkToBool(fFlags & kLinearizeColorAttribute_GPFlag);
64fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        SkASSERT(!linearize || (fFlags & kColorAttributeIsSkColor_GPFlag));
65fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        return linearize;
66fa6d865215b48fac4ee24c120736e500d418f641Brian Osman    }
679b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
6857d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel    class GLSLProcessor : public GrGLSLGeometryProcessor {
694973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt    public:
7057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel        GLSLProcessor()
715559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL), fCoverage(0xff) {}
724973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
7336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein        void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
742dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt            const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
754ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel            GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
768528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton            GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
770eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel            GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
787ea439b2203855db97330b25945b87dd4b170b8begdaniel            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
794973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
80abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt            // emit attributes
810eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel            varyingHandler->emitAttributes(gp);
822dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt
832dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt            // Setup pass through color
84bfd5183b9e039b50fb33441d1f90130b8eced80aBrian Salomon            if (gp.hasVertexColor()) {
853de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                GrGLSLVertToFrag varying(kVec4f_GrSLType);
863de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                varyingHandler->addVarying("color", &varying);
87fa6d865215b48fac4ee24c120736e500d418f641Brian Osman
88fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                // There are several optional steps to process the color. Start with the attribute:
89fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                vertBuilder->codeAppendf("vec4 color = %s;", gp.inColor()->fName);
90fa6d865215b48fac4ee24c120736e500d418f641Brian Osman
91fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                // Linearize
92fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                if (gp.linearizeColor()) {
93fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    SkString srgbFuncName;
94fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    static const GrShaderVar gSrgbArgs[] = {
95fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                        GrShaderVar("x", kFloat_GrSLType),
96fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    };
97fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    vertBuilder->emitFunction(kFloat_GrSLType,
98fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                              "srgb_to_linear",
99fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                              SK_ARRAY_COUNT(gSrgbArgs),
100fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                              gSrgbArgs,
101fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                              "return (x <= 0.04045) ? (x / 12.92) "
102fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                              ": pow((x + 0.055) / 1.055, 2.4);",
103fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                              &srgbFuncName);
104fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    vertBuilder->codeAppendf("color = vec4(%s(%s.r), %s(%s.g), %s(%s.b), %s.a);",
105fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                             srgbFuncName.c_str(), gp.inColor()->fName,
106fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                             srgbFuncName.c_str(), gp.inColor()->fName,
107fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                             srgbFuncName.c_str(), gp.inColor()->fName,
1083de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                                             gp.inColor()->fName);
1093de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                }
110fa6d865215b48fac4ee24c120736e500d418f641Brian Osman
111fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                // For SkColor, do a red/blue swap and premul
112fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                if (gp.fFlags & kColorAttributeIsSkColor_GPFlag) {
113fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    vertBuilder->codeAppend("color = vec4(color.a * color.bgr, color.a);");
114fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                }
115fa6d865215b48fac4ee24c120736e500d418f641Brian Osman
116fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                // Do color-correction to destination gamut
117fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                if (gp.linearizeColor()) {
118fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    fColorSpaceHelper.emitCode(uniformHandler, gp.fColorSpaceXform.get(),
119fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                               kVertex_GrShaderFlag);
120fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    if (fColorSpaceHelper.isValid()) {
121fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                        SkString xformedColor;
122fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                        vertBuilder->appendColorGamutXform(&xformedColor, "color",
123fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                                           &fColorSpaceHelper);
124fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                        vertBuilder->codeAppendf("color = %s;", xformedColor.c_str());
125fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                    }
126fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                }
127fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                vertBuilder->codeAppendf("%s = color;\n", varying.vsOut());
1283de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon                fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
129bfd5183b9e039b50fb33441d1f90130b8eced80aBrian Salomon            } else {
130bfd5183b9e039b50fb33441d1f90130b8eced80aBrian Salomon                this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
131bfd5183b9e039b50fb33441d1f90130b8eced80aBrian Salomon                                        &fColorUniform);
132b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            }
133b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt
134abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt            // Setup position
1357ea439b2203855db97330b25945b87dd4b170b8begdaniel            this->setupPosition(vertBuilder,
1367ea439b2203855db97330b25945b87dd4b170b8begdaniel                                uniformHandler,
1374ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                gpArgs,
1384ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                gp.inPosition()->fName,
1394ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                gp.viewMatrix(),
1405559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt                                &fViewMatrixUniform);
1414973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
142b2aa7cb90f4c66125056bac70dbca2093dd5ba41joshualitt            if (gp.hasExplicitLocalCoords()) {
143abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                // emit transforms with explicit local coords
1447ea439b2203855db97330b25945b87dd4b170b8begdaniel                this->emitTransforms(vertBuilder,
1450eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel                                     varyingHandler,
1467ea439b2203855db97330b25945b87dd4b170b8begdaniel                                     uniformHandler,
1474ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     gpArgs->fPositionVar,
1484ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     gp.inLocalCoords()->fName,
1494ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     gp.localMatrix(),
150a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                                     args.fFPCoordTransformHandler);
151abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt            } else {
152abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt                // emit transforms with position
1537ea439b2203855db97330b25945b87dd4b170b8begdaniel                this->emitTransforms(vertBuilder,
1540eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel                                     varyingHandler,
1557ea439b2203855db97330b25945b87dd4b170b8begdaniel                                     uniformHandler,
1564ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     gpArgs->fPositionVar,
1574ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     gp.inPosition()->fName,
1584ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel                                     gp.localMatrix(),
159a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                                     args.fFPCoordTransformHandler);
160abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt            }
161abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt
1622dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt            // Setup coverage as pass through
1638c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            if (gp.hasVertexCoverage()) {
1648c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                fragBuilder->codeAppendf("float alpha = 1.0;");
1658c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                varyingHandler->addPassThroughAttribute(gp.inCoverage(), "alpha");
1668c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                fragBuilder->codeAppendf("%s = vec4(alpha);", args.fOutputCoverage);
1678c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            } else if (gp.coverage() == 0xff) {
1688c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
1698c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            } else {
1708c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                const char* fragCoverage;
1718c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                fCoverageUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
1728c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                                                              kFloat_GrSLType,
1738c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                                                              kDefault_GrSLPrecision,
1748c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                                                              "Coverage",
1758c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                                                              &fragCoverage);
1768c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                fragBuilder->codeAppendf("%s = vec4(%s);", args.fOutputCoverage, fragCoverage);
1772dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt            }
1784973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt        }
1794973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
18087f48d997ec29e5eeaa7567355775e93465dd60djoshualitt        static inline void GenKey(const GrGeometryProcessor& gp,
18194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon                                  const GrShaderCaps&,
18287f48d997ec29e5eeaa7567355775e93465dd60djoshualitt                                  GrProcessorKeyBuilder* b) {
1832dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt            const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
1848fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt            uint32_t key = def.fFlags;
1853de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon            key |= (def.coverage() == 0xff) ? 0x10 : 0;
1863de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon            key |= (def.localCoordsWillBeRead() && def.localMatrix().hasPerspective()) ? 0x20 : 0x0;
1873de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon            key |= ComputePosKey(def.viewMatrix()) << 20;
1888fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt            b->add32(key);
189fa6d865215b48fac4ee24c120736e500d418f641Brian Osman            if (def.linearizeColor()) {
190fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                b->add32(GrColorSpaceXform::XformKey(def.fColorSpaceXform.get()));
191fa6d865215b48fac4ee24c120736e500d418f641Brian Osman            }
1922dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        }
1934973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
194018fb62d12d1febf121fe265da5b6117b86a6541egdaniel        void setData(const GrGLSLProgramDataManager& pdman,
195a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                     const GrPrimitiveProcessor& gp,
196a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon                     FPCoordTransformIter&& transformIter) override {
197e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt            const DefaultGeoProc& dgp = gp.cast<DefaultGeoProc>();
1985559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt
1995559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            if (!dgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dgp.viewMatrix())) {
2005559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt                fViewMatrix = dgp.viewMatrix();
201018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                float viewMatrix[3 * 3];
20264c4728c70001ed074fecf5c4e083781987b12e9egdaniel                GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
2035559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt                pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
2045559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt            }
205ee2af95db72152dfa61c841875df0594ca93437djoshualitt
206b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt            if (dgp.color() != fColor && !dgp.hasVertexColor()) {
207018fb62d12d1febf121fe265da5b6117b86a6541egdaniel                float c[4];
208b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                GrColorToRGBAFloat(dgp.color(), c);
2099b98932adaceb7ad0a617ade16616923f6bffe84joshualitt                pdman.set4fv(fColorUniform, 1, c);
210b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                fColor = dgp.color();
2119b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            }
212b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt
2138c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            if (dgp.coverage() != fCoverage && !dgp.hasVertexCoverage()) {
214b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.coverage()));
215b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                fCoverage = dgp.coverage();
2169b98932adaceb7ad0a617ade16616923f6bffe84joshualitt            }
217a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3bsalomon            this->setTransformDataHelper(dgp.fLocalMatrix, pdman, &transformIter);
218fa6d865215b48fac4ee24c120736e500d418f641Brian Osman
219fa6d865215b48fac4ee24c120736e500d418f641Brian Osman            if (dgp.linearizeColor() && dgp.fColorSpaceXform) {
220fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                fColorSpaceHelper.setData(pdman, dgp.fColorSpaceXform.get());
221fa6d865215b48fac4ee24c120736e500d418f641Brian Osman            }
222e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt        }
223e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt
2244973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt    private:
2255559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        SkMatrix fViewMatrix;
2269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        GrColor fColor;
2279b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        uint8_t fCoverage;
2285559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt        UniformHandle fViewMatrixUniform;
2299b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        UniformHandle fColorUniform;
2309b98932adaceb7ad0a617ade16616923f6bffe84joshualitt        UniformHandle fCoverageUniform;
231fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        GrGLSLColorSpaceXformHelper fColorSpaceHelper;
2329b98932adaceb7ad0a617ade16616923f6bffe84joshualitt
233e659a581f63fdccb64dce2dc8a478cf56831feeaegdaniel        typedef GrGLSLGeometryProcessor INHERITED;
2344973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt    };
2354973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
23694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
23757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel        GLSLProcessor::GenKey(*this, caps, b);
238eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
239eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
24094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
24157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel        return new GLSLProcessor();
242eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt    }
243eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt
2444973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualittprivate:
2458059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    DefaultGeoProc(uint32_t gpTypeFlags,
2468059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                   GrColor color,
247fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                   sk_sp<GrColorSpaceXform> colorSpaceXform,
2488059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                   const SkMatrix& viewMatrix,
2498059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                   const SkMatrix& localMatrix,
250b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt                   uint8_t coverage,
2518c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon                   bool localCoordsWillBeRead)
2523de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon            : fColor(color)
2538c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            , fViewMatrix(viewMatrix)
2548c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            , fLocalMatrix(localMatrix)
2558c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            , fCoverage(coverage)
2568c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon            , fFlags(gpTypeFlags)
257fa6d865215b48fac4ee24c120736e500d418f641Brian Osman            , fLocalCoordsWillBeRead(localCoordsWillBeRead)
258fa6d865215b48fac4ee24c120736e500d418f641Brian Osman            , fColorSpaceXform(std::move(colorSpaceXform)) {
259eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt        this->initClassID<DefaultGeoProc>();
2606cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon        fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
2616cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon                                             kHigh_GrSLPrecision);
2623de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        if (fFlags & kColorAttribute_GPFlag) {
2636cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon            fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
2642dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        }
2653de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        if (fFlags & kLocalCoordAttribute_GPFlag) {
2669b345e3615a19f72ecae897c328a64662caf1370Brian Salomon            fInLocalCoords = &this->addVertexAttrib("inLocalCoord", kVec2f_GrVertexAttribType,
2679b345e3615a19f72ecae897c328a64662caf1370Brian Salomon                                                    kHigh_GrSLPrecision);
268cc6aeee67509680e6a82a3024de2fd8562e0afd3bsalomon            this->setHasExplicitLocalCoords();
2692dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        }
2703de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        if (fFlags & kCoverageAttribute_GPFlag) {
2716cb807bf99ac0f8f166e1790f91bcb3afbfb5458bsalomon            fInCoverage = &this->addVertexAttrib("inCoverage", kFloat_GrVertexAttribType);
2722dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt        }
2732dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    }
2744973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
2753de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    const Attribute* fInPosition = nullptr;
2763de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    const Attribute* fInColor = nullptr;
2773de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    const Attribute* fInLocalCoords = nullptr;
2783de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    const Attribute* fInCoverage = nullptr;
27988c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt    GrColor fColor;
280e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt    SkMatrix fViewMatrix;
281e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt    SkMatrix fLocalMatrix;
2829b98932adaceb7ad0a617ade16616923f6bffe84joshualitt    uint8_t fCoverage;
2832dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    uint32_t fFlags;
2847765a477ee3ca5e2c6ada1e16c31dfaae2079240bsalomon    bool fLocalCoordsWillBeRead;
285fa6d865215b48fac4ee24c120736e500d418f641Brian Osman    sk_sp<GrColorSpaceXform> fColorSpaceXform;
2864973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
2870c26a9dbd0b6546731df63c01411cb2aaa5ba236Brian Salomon    GR_DECLARE_GEOMETRY_PROCESSOR_TEST
2885478d427c6e67c986a3390162c8fec77c466058ajoshualitt
2892e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    typedef GrGeometryProcessor INHERITED;
2904973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt};
2914973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
2924973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
2934973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt
2946f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
29506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrGeometryProcessor> DefaultGeoProc::TestCreate(GrProcessorTestData* d) {
2962dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    uint32_t flags = 0;
2970067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    if (d->fRandom->nextBool()) {
2983de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        flags |= kColorAttribute_GPFlag;
299b2aa7cb90f4c66125056bac70dbca2093dd5ba41joshualitt    }
300b2aa7cb90f4c66125056bac70dbca2093dd5ba41joshualitt    if (d->fRandom->nextBool()) {
3013de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        flags |= kColorAttributeIsSkColor_GPFlag;
3024973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt    }
3030067ff5e0f85084dd2b5ad9886b526482b89a116joshualitt    if (d->fRandom->nextBool()) {
3043de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        flags |= kCoverageAttribute_GPFlag;
3053de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    }
3063de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    if (d->fRandom->nextBool()) {
3073de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        flags |= kLocalCoordAttribute_GPFlag;
3082dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt    }
3095478d427c6e67c986a3390162c8fec77c466058ajoshualitt
31006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return DefaultGeoProc::Make(flags,
31106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                GrRandomColor(d->fRandom),
312fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                GrTest::TestColorXform(d->fRandom),
31306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                GrTest::TestMatrix(d->fRandom),
31406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                GrTest::TestMatrix(d->fRandom),
31506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                d->fRandom->nextBool(),
31606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                GrRandomCoverage(d->fRandom));
3175478d427c6e67c986a3390162c8fec77c466058ajoshualitt}
3186f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
3195478d427c6e67c986a3390162c8fec77c466058ajoshualitt
32006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrGeometryProcessor> GrDefaultGeoProcFactory::Make(const Color& color,
32106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                         const Coverage& coverage,
32206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                         const LocalCoords& localCoords,
32306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                                         const SkMatrix& viewMatrix) {
324e9d6095674979a9b843c291b85746922e9ac181ajoshualitt    uint32_t flags = 0;
3253de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    if (Color::kPremulGrColorAttribute_Type == color.fType) {
3263de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        flags |= kColorAttribute_GPFlag;
3273de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    } else if (Color::kUnpremulSkColorAttribute_Type == color.fType) {
3283de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon        flags |= kColorAttribute_GPFlag | kColorAttributeIsSkColor_GPFlag;
3293de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    }
330fa6d865215b48fac4ee24c120736e500d418f641Brian Osman    if (color.fLinearize) {
331fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        // It only makes sense to linearize SkColors (which are always sRGB). GrColor values should
332fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        // have been linearized and gamut-converted during paint conversion
333fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        SkASSERT(Color::kUnpremulSkColorAttribute_Type == color.fType);
334fa6d865215b48fac4ee24c120736e500d418f641Brian Osman        flags |= kLinearizeColorAttribute_GPFlag;
335fa6d865215b48fac4ee24c120736e500d418f641Brian Osman    }
3363de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    flags |= coverage.fType == Coverage::kAttribute_Type ? kCoverageAttribute_GPFlag : 0;
3373de0aee181b8fe0013b15100cba7381eb0468db4Brian Salomon    flags |= localCoords.fType == LocalCoords::kHasExplicit_Type ? kLocalCoordAttribute_GPFlag : 0;
338e9d6095674979a9b843c291b85746922e9ac181ajoshualitt
339e9d6095674979a9b843c291b85746922e9ac181ajoshualitt    uint8_t inCoverage = coverage.fCoverage;
3400d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt    bool localCoordsWillBeRead = localCoords.fType != LocalCoords::kUnused_Type;
341e9d6095674979a9b843c291b85746922e9ac181ajoshualitt
342e9d6095674979a9b843c291b85746922e9ac181ajoshualitt    GrColor inColor = color.fColor;
34306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return DefaultGeoProc::Make(flags,
34406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                inColor,
345fa6d865215b48fac4ee24c120736e500d418f641Brian Osman                                color.fColorSpaceXform,
34606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                viewMatrix,
34706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                localCoords.fMatrix ? *localCoords.fMatrix : SkMatrix::I(),
34806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                localCoordsWillBeRead,
34906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                                inCoverage);
350e9d6095674979a9b843c291b85746922e9ac181ajoshualitt}
3510d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt
35206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrGeometryProcessor> GrDefaultGeoProcFactory::MakeForDeviceSpace(
3530d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt                                                                     const Color& color,
3540d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt                                                                     const Coverage& coverage,
3550d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt                                                                     const LocalCoords& localCoords,
3560d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt                                                                     const SkMatrix& viewMatrix) {
3570d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt    SkMatrix invert = SkMatrix::I();
358df0c55785033c191d2d509c22662861588e4acd8joshualitt    if (LocalCoords::kUnused_Type != localCoords.fType) {
359df0c55785033c191d2d509c22662861588e4acd8joshualitt        SkASSERT(LocalCoords::kUsePosition_Type == localCoords.fType);
360df0c55785033c191d2d509c22662861588e4acd8joshualitt        if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
36196fcdcc219d2a0d3579719b84b28bede76efba64halcanary            return nullptr;
362df0c55785033c191d2d509c22662861588e4acd8joshualitt        }
3630d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt
364df0c55785033c191d2d509c22662861588e4acd8joshualitt        if (localCoords.hasLocalMatrix()) {
365df0c55785033c191d2d509c22662861588e4acd8joshualitt            invert.preConcat(*localCoords.fMatrix);
366df0c55785033c191d2d509c22662861588e4acd8joshualitt        }
3670d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt    }
3680d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt
3690d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt    LocalCoords inverted(LocalCoords::kUsePosition_Type, &invert);
37006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    return Make(color, coverage, inverted, SkMatrix::I());
3710d986d877edae36ad7dc6fbdbc69a56ca9372702joshualitt}
372