18072caa80384292858d31ae34b7e19768875866bjoshualitt/*
28072caa80384292858d31ae34b7e19768875866bjoshualitt * Copyright 2013 Google Inc.
38072caa80384292858d31ae34b7e19768875866bjoshualitt *
48072caa80384292858d31ae34b7e19768875866bjoshualitt * Use of this source code is governed by a BSD-style license that can be
58072caa80384292858d31ae34b7e19768875866bjoshualitt * found in the LICENSE file.
68072caa80384292858d31ae34b7e19768875866bjoshualitt */
78072caa80384292858d31ae34b7e19768875866bjoshualitt
88072caa80384292858d31ae34b7e19768875866bjoshualitt#ifndef GrPrimitiveProcessor_DEFINED
98072caa80384292858d31ae34b7e19768875866bjoshualitt#define GrPrimitiveProcessor_DEFINED
108072caa80384292858d31ae34b7e19768875866bjoshualitt
118072caa80384292858d31ae34b7e19768875866bjoshualitt#include "GrColor.h"
128072caa80384292858d31ae34b7e19768875866bjoshualitt#include "GrProcessor.h"
138072caa80384292858d31ae34b7e19768875866bjoshualitt#include "GrShaderVar.h"
148072caa80384292858d31ae34b7e19768875866bjoshualitt
158072caa80384292858d31ae34b7e19768875866bjoshualitt/*
168072caa80384292858d31ae34b7e19768875866bjoshualitt * The GrPrimitiveProcessor represents some kind of geometric primitive.  This includes the shape
178072caa80384292858d31ae34b7e19768875866bjoshualitt * of the primitive and the inherent color of the primitive.  The GrPrimitiveProcessor is
188072caa80384292858d31ae34b7e19768875866bjoshualitt * responsible for providing a color and coverage input into the Ganesh rendering pipeline.  Through
198072caa80384292858d31ae34b7e19768875866bjoshualitt * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
208072caa80384292858d31ae34b7e19768875866bjoshualitt * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
2109d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon * functionality.
228072caa80384292858d31ae34b7e19768875866bjoshualitt *
238072caa80384292858d31ae34b7e19768875866bjoshualitt * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
24cb30bb2cb727e276792812c6390547dba474c831Brian Salomon * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final
25cb30bb2cb727e276792812c6390547dba474c831Brian Salomon * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
26cb30bb2cb727e276792812c6390547dba474c831Brian Salomon * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
27a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon * getProcessorAnalysisInputs implementation. These seed values are processed by the
285298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon * subsequent
2992aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
3092aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon * the applyPipelineOptimizations call, where the op can use the information to inform decisions
3192aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon * about GrPrimitiveProcessor creation.
328072caa80384292858d31ae34b7e19768875866bjoshualitt */
338072caa80384292858d31ae34b7e19768875866bjoshualitt
34e659a581f63fdccb64dce2dc8a478cf56831feeaegdanielclass GrGLSLPrimitiveProcessor;
358072caa80384292858d31ae34b7e19768875866bjoshualitt
368072caa80384292858d31ae34b7e19768875866bjoshualitt/*
378072caa80384292858d31ae34b7e19768875866bjoshualitt * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
388072caa80384292858d31ae34b7e19768875866bjoshualitt * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
398072caa80384292858d31ae34b7e19768875866bjoshualitt * pipelines, and they must provide some notion of equality
408072caa80384292858d31ae34b7e19768875866bjoshualitt */
41d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomonclass GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
428072caa80384292858d31ae34b7e19768875866bjoshualittpublic:
438072caa80384292858d31ae34b7e19768875866bjoshualitt    struct Attribute {
441d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        enum class InputRate : bool {
451d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton            kPerVertex,
461d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton            kPerInstance
471d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        };
4804460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon        GrShaderVar asShaderVar() const {
4904460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon            return GrShaderVar(fName, GrVertexAttribTypeToSLType(fType),
5004460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon                               GrShaderVar::kIn_TypeModifier);
5104460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon        }
52b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon        bool isInitialized() const { return SkToBool(fName); }
53b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon        Attribute() = default;
54b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon        Attribute(const char* name, GrVertexAttribType type, int offset, InputRate rate)
55b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon                : fName(name), fType(type), fOffsetInRecord(offset), fInputRate(rate) {}
56b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon        const char*          fName = nullptr;
571d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        GrVertexAttribType   fType;
581d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        int                  fOffsetInRecord;
591d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        InputRate            fInputRate;
608072caa80384292858d31ae34b7e19768875866bjoshualitt    };
618072caa80384292858d31ae34b7e19768875866bjoshualitt
62abff956455637b12eab374fd44b99e1338799113Ethan Nicholas    GrPrimitiveProcessor(ClassID classID)
63abff956455637b12eab374fd44b99e1338799113Ethan Nicholas    : GrResourceIOProcessor(classID) {}
64abff956455637b12eab374fd44b99e1338799113Ethan Nicholas
657dbd45d2c7427d2c679d6507435d2f0220bf64efbsalomon    int numAttribs() const { return fAttribs.count(); }
667dbd45d2c7427d2c679d6507435d2f0220bf64efbsalomon    const Attribute& getAttrib(int index) const { return fAttribs[index]; }
678072caa80384292858d31ae34b7e19768875866bjoshualitt
681d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    bool hasVertexAttribs() const { return SkToBool(fVertexStride); }
691d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); }
701d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
711d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    /**
721d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * These return the strides of the vertex and instance buffers. Attributes are expected to be
731d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord
741d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * indicates an attribute's location in bytes relative to the first attribute. (These are padded
751d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * to the nearest 4 bytes for performance reasons.)
761d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     *
771d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * A common practice is to populate the buffer's memory using an implicit array of structs. In
781d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * this case, it is best to assert:
791d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     *
801d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     *     stride == sizeof(struct) and
811d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     *     offsetof(struct, field[i]) == attrib[i].fOffsetInRecord
821d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     *
831d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses.
841d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     */
851d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    int getVertexStride() const { return fVertexStride; }
861d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    int getInstanceStride() const { return fInstanceStride; }
871d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
881d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
891d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    // we put these calls on the base class to prevent having to cast
901d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    virtual bool willUseGeoShader() const = 0;
918072caa80384292858d31ae34b7e19768875866bjoshualitt
9227059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    bool willUsePrimitiveRestart() const { return fWillUsePrimitiveRestart; }
9327059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton
948072caa80384292858d31ae34b7e19768875866bjoshualitt    /**
95a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix     * Computes a transformKey from an array of coord transforms. Will only look at the first
96a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix     * <numCoords> transforms in the array.
97a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix     *
98a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix     * TODO: A better name for this function  would be "compute" instead of "get".
998072caa80384292858d31ae34b7e19768875866bjoshualitt     */
100a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix    uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
101a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix                             int numCoords) const;
1028072caa80384292858d31ae34b7e19768875866bjoshualitt
1038072caa80384292858d31ae34b7e19768875866bjoshualitt    /**
1048072caa80384292858d31ae34b7e19768875866bjoshualitt     * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
1058072caa80384292858d31ae34b7e19768875866bjoshualitt     * processor's GL backend implementation.
106a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix     *
107a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix     * TODO: A better name for this function  would be "compute" instead of "get".
1088072caa80384292858d31ae34b7e19768875866bjoshualitt     */
10994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
1108072caa80384292858d31ae34b7e19768875866bjoshualitt
1118072caa80384292858d31ae34b7e19768875866bjoshualitt
1128072caa80384292858d31ae34b7e19768875866bjoshualitt    /** Returns a new instance of the appropriate *GL* implementation class
1138072caa80384292858d31ae34b7e19768875866bjoshualitt        for the given GrProcessor; caller is responsible for deleting
1148072caa80384292858d31ae34b7e19768875866bjoshualitt        the object. */
11594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
1168072caa80384292858d31ae34b7e19768875866bjoshualitt
1172279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas    virtual bool isPathRendering() const { return false; }
1188072caa80384292858d31ae34b7e19768875866bjoshualitt
1192279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas    /**
1202279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas     * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
1212279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas     */
1222279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas    virtual const char* getDestColorOverride() const { return nullptr; }
1239d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
12428ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas    virtual float getSampleShading() const {
12528ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas        return 0.0;
12628ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas    }
12728ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas
1288072caa80384292858d31ae34b7e19768875866bjoshualittprotected:
1291d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    /**
1301d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     * Subclasses call these from their constructor to register vertex and instance attributes.
1311d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton     */
132fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas    const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type) {
133fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas        fAttribs.push_back() = {name, type, fVertexStride, Attribute::InputRate::kPerVertex};
1341d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
1351d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        return fAttribs.back();
1361d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    }
137fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas    const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type) {
138fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas        fAttribs.push_back() = {name, type, fInstanceStride, Attribute::InputRate::kPerInstance};
1391d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
1401d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton        return fAttribs.back();
1411d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    }
1428072caa80384292858d31ae34b7e19768875866bjoshualitt
14327059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    void setWillUsePrimitiveRestart() { fWillUsePrimitiveRestart = true; }
14427059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton
1458072caa80384292858d31ae34b7e19768875866bjoshualittprivate:
146d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon    void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
147d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon    void removeRefs() const override { GrResourceIOProcessor::removeRefs(); }
148d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon    void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
149fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein    void notifyRefCntIsZero() const final {}
1508072caa80384292858d31ae34b7e19768875866bjoshualitt    virtual bool hasExplicitLocalCoords() const = 0;
1518072caa80384292858d31ae34b7e19768875866bjoshualitt
15227059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    SkSTArray<8, Attribute> fAttribs;
15327059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    int fVertexStride = 0;
15427059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    int fInstanceStride = 0;
15527059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton    bool fWillUsePrimitiveRestart = false;
1561d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
1578072caa80384292858d31ae34b7e19768875866bjoshualitt    typedef GrProcessor INHERITED;
1588072caa80384292858d31ae34b7e19768875866bjoshualitt};
1598072caa80384292858d31ae34b7e19768875866bjoshualitt
1608072caa80384292858d31ae34b7e19768875866bjoshualitt#endif
161